Как SQL Server допускает использование нескольких одинаковых псевдонимов в одном операторе SELECT?

Я делал несколько запросов с помощью Dapper и наткнулся на вариант использования, когда мне нужно было возвращать разные столбцы, используя один и тот же псевдоним, чтобы иметь возможность сопоставлять их с разными объектами с одним и тем же именем свойства, например. Teacher.Name и Student.Name. Я также использовал представление, и оно жаловалось на то, что не разрешает столбцы с одинаковыми именами. Поэтому я присвоил столбцам разные имена в представлении, а затем при выборе из представления я снова присвоил им те же имена, и это сработало, чего я не ожидал. Я также не смог найти никаких ресурсов по этому поводу.

Пример: https://sqlfiddle.com/sql-server/online-compiler?id=4e489d23-e1db-4655-ad8e-493324700b09

CREATE TABLE users (
    id INT,
    name VARCHAR(50),
    date DATE
);

-- Insert test data
INSERT INTO users (id, name, date)
VALUES (1, 'John Doe', '2024-01-01'),
       (2, 'Jane Smith', '2024-01-02');

-- Test the SELECT statement with the same alias for different columns
SELECT 
    id, 
    name AS alias_name, 
    date AS alias_name 
FROM 
    users;

-- Clean up
DROP TABLE users;

причина, по которой это не разрешено в представлениях, заключается в том, что когда вы выбираете из представления, как сервер sql узнает, какой из повторяющихся столбцов вам действительно нужен. Для прямых запросов не имеет значения, совпадают ли псевдонимы. Но вы заметите, что помещение вашего запроса в подзапрос и выбор из него не удастся по тем же причинам, поскольку сервер снова не может определить, какой из дубликатов вам нужен.

siggemannen 05.07.2024 13:02

Почему это имеет значение для SQL-сервера? Он не пытается получить доступ к этим псевдонимам.

Dale K 05.07.2024 13:03

Реальная проблема, описанная выше, скорее всего, возникнет на уровне вашего приложения. Если вы вернете 2 столбца во внешнем SELECT с одним и тем же псевдонимом (alias_name здесь), то при попытке сослаться на столбец alias_name в коде вашего приложения (C#, Python, Java и т. д.) он не будет знать, что это за столбец. как есть 2 с таким именем. SQL Server «заботится» только тогда, когда вы заставляете его делать что-то подобное, например, помещать запрос в CTE/подзапрос/производную таблицу и т. д. Поскольку псевдоним находится во внешнем SELECT, псевдоним является скорее значением «представления». , что не влияет на сам SQL Server.

Thom A 05.07.2024 13:13

Iirc dapper может справиться с этим, потому что вы можете вернуть плоский набор результатов, который разбивается на несколько объектов, и допускаются повторяющиеся имена столбцов. Я предполагаю, что изящный доступ осуществляется через порядковый номер, но все равно может получить доступ к имени столбца.

Dale K 05.07.2024 13:22

Да, я больше думаю о том, сделали ли вы в коде своего приложения что-то вроде (в псевдокоде) for each row in dataset { if row.alias_name == 'My Value' { <Do X> } }, @DaleK. Я подозреваю, что во многих языках приложений возникнет «проблема» с двусмысленностью row.alias_name или в момент определения row.

Thom A 05.07.2024 13:25

Если вы добавите ORDER BY alias_name, это снова станет проблемой SQL Server, и вы получите Ambiguous column name 'alias_name'

Martin Smith 05.07.2024 14:21
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
6
87
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Запрос SELECT SQL верхнего уровня может иметь несколько столбцов с одинаковым именем и даже столбцы без имени.

Обычно API запросов позволяет вам получать эти столбцы по имени («id», «имя», «сумма» и т. д.) или по порядковому номеру (1, 2, 3 и т. д.). В вашем случае получить их по имени невозможно. Вам нужно будет получить их по порядковому номеру. Фактически я реализовал чтение по порядковому номеру в написанном мной API, чтобы избежать путаницы с именами столбцов при объединении нескольких таблиц, которые могут привести к конфликту имен в области запроса.

Представления также должны иметь разные имена для всех столбцов, возникающих из них, поскольку SQL обрабатывает их как объекты базы данных, подобные таблицам.

Когда дело доходит до подзапросов SELECT:

  1. Однако подзапрос табличного выражения (FROM, JOIN, LATERAL, <запятая>) должен иметь четко идентифицированные столбцы, чтобы их можно было использовать в области внешнего уровня запроса.

  2. Скалярные подзапросы (запросы, возвращающие один столбец) могут иметь или не иметь имя столбца.

  3. Асимметричные запросы (модификаторы ANY/ALL) могут иметь или не иметь одинаковые/одинаковые имена; Запросы существования ([NOT] EXISTS, [NOT] IN) попадают в ту же категорию.

Другие вопросы по теме