Я делал несколько запросов с помощью 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-сервера? Он не пытается получить доступ к этим псевдонимам.
Реальная проблема, описанная выше, скорее всего, возникнет на уровне вашего приложения. Если вы вернете 2 столбца во внешнем SELECT
с одним и тем же псевдонимом (alias_name
здесь), то при попытке сослаться на столбец alias_name
в коде вашего приложения (C#, Python, Java и т. д.) он не будет знать, что это за столбец. как есть 2 с таким именем. SQL Server «заботится» только тогда, когда вы заставляете его делать что-то подобное, например, помещать запрос в CTE/подзапрос/производную таблицу и т. д. Поскольку псевдоним находится во внешнем SELECT
, псевдоним является скорее значением «представления». , что не влияет на сам SQL Server.
Iirc dapper может справиться с этим, потому что вы можете вернуть плоский набор результатов, который разбивается на несколько объектов, и допускаются повторяющиеся имена столбцов. Я предполагаю, что изящный доступ осуществляется через порядковый номер, но все равно может получить доступ к имени столбца.
Да, я больше думаю о том, сделали ли вы в коде своего приложения что-то вроде (в псевдокоде) for each row in dataset { if row.alias_name == 'My Value' { <Do X> } }
, @DaleK. Я подозреваю, что во многих языках приложений возникнет «проблема» с двусмысленностью row.alias_name
или в момент определения row
.
Если вы добавите ORDER BY alias_name
, это снова станет проблемой SQL Server, и вы получите Ambiguous column name 'alias_name'
Запрос SELECT SQL верхнего уровня может иметь несколько столбцов с одинаковым именем и даже столбцы без имени.
Обычно API запросов позволяет вам получать эти столбцы по имени («id», «имя», «сумма» и т. д.) или по порядковому номеру (1, 2, 3 и т. д.). В вашем случае получить их по имени невозможно. Вам нужно будет получить их по порядковому номеру. Фактически я реализовал чтение по порядковому номеру в написанном мной API, чтобы избежать путаницы с именами столбцов при объединении нескольких таблиц, которые могут привести к конфликту имен в области запроса.
Представления также должны иметь разные имена для всех столбцов, возникающих из них, поскольку SQL обрабатывает их как объекты базы данных, подобные таблицам.
Когда дело доходит до подзапросов SELECT:
Однако подзапрос табличного выражения (FROM, JOIN, LATERAL, <запятая>) должен иметь четко идентифицированные столбцы, чтобы их можно было использовать в области внешнего уровня запроса.
Скалярные подзапросы (запросы, возвращающие один столбец) могут иметь или не иметь имя столбца.
Асимметричные запросы (модификаторы ANY/ALL) могут иметь или не иметь одинаковые/одинаковые имена; Запросы существования ([NOT] EXISTS, [NOT] IN) попадают в ту же категорию.
причина, по которой это не разрешено в представлениях, заключается в том, что когда вы выбираете из представления, как сервер sql узнает, какой из повторяющихся столбцов вам действительно нужен. Для прямых запросов не имеет значения, совпадают ли псевдонимы. Но вы заметите, что помещение вашего запроса в подзапрос и выбор из него не удастся по тем же причинам, поскольку сервер снова не может определить, какой из дубликатов вам нужен.