Підсумок
Немає жодної логічної причини, що цього не вдалося зробити, але користь невелика, і є деякі підводні камені, які можуть виявитись не відразу.
Результати досліджень
Я провів кілька досліджень і знайшов хорошу інформацію. Нижче наводиться пряма цитата надійного первинного джерела (який хоче залишатись анонімним) на 2012-08-09 17:49 GMT:
Коли SQL був вперше винайдений, у нього не було псевдонімів SELECT. Це був серйозний недолік, який було виправлено, коли мова була стандартизована ANSI приблизно в 1986 році.
Мова повинна була бути "непроцедурною" - іншими словами, описати потрібні вам дані, не вказуючи, як їх знайти. Отже, наскільки я знаю, немає жодної причини, по якій реалізація SQL не могла проаналізувати весь запит перед його обробкою, і дозволить визначати псевдоніми де-небудь і використовувати їх всюди. Наприклад, я не бачу жодної причини, чому наступний запит не повинен бути дійсним:
select name, salary + bonus as pay
from employee
where pay > 100000
Хоча я вважаю, що це розумний запит, деякі системи, що базуються на SQL, можуть ввести обмеження на використання псевдонімів з якоїсь причини, пов'язаної з реалізацією. Я не здивований, коли чує, що SQL Server це робить.
Мене цікавлять подальші дослідження стандарту SQL-86, і чому сучасні СУБД не підтримують повторне використання псевдоніму, але ще не встигли зайнятися цим. Для початку я не знаю, де взяти документацію або як з’ясувати, хто саме склав комітет. Хтось може допомогти? Я також хотів би дізнатися більше про оригінальний продукт Sybase, з якого походить SQL Server.
З цього дослідження та деякої подальшої думки я підозрюю, що використання псевдонімів в інших статтях, хоча це цілком можливо, просто ніколи не було таким пріоритетним для виробників СУБД порівняно з іншими мовними особливостями. Оскільки це не стільки перешкода, тому що легко обійдений автором запитів, прикладання зусиль над іншими досягненнями не є оптимальним. Крім того, це було б власником, оскільки воно, очевидно, не є частиною стандарту SQL (хоча я чекаю, щоб дізнатися про це напевне), і, таким чином, було б незначне поліпшення, порушуючи сумісність SQL між СУБД. Для порівняння CROSS APPLY
(що насправді є не що інше, як похідна таблиця із зовнішніми посиланнями) - це величезна зміна, яка в той час як патентований пропонує неймовірну виразну силу, яку не легко виконати іншими способами.
Проблеми з використанням псевдонімів скрізь
Якщо ви можете додати елементи SELECT до пункту WHERE, ви можете не тільки підірвати складність запиту (і, таким чином, складність пошуку хорошого плану виконання), можна придумати абсолютно нелогічний матеріал. Спробуйте:
SELECT X + 5 Y FROM MyTable WHERE Y = X
Що робити, якщо в MyTable вже є стовпець Y, на який посилається пункт WHERE? Рішення полягає у використанні CTE або отриманої таблиці, яка в більшості випадків не повинна коштувати додатково, але досягає того ж кінцевого кінцевого результату. CTE та похідні таблиці принаймні примушують вирішити неоднозначність, дозволяючи псевдонім використовувати лише один раз.
Крім того, використання псевдонімів у пункті FROM має видатний сенс. Ви не можете цього зробити:
SELECT
T3.ID + (SELECT Min(Interval) FROM Intervals WHERE IntName = 'T') CalcID
FROM
Table1 T
INNER JOIN Table2 T2
ON T2.ID = CalcID
INNER JOIN Table3 T3
ON T2.ID = T3.ID
Це кругле посилання (в тому сенсі, що T2 таємно посилається на значення з T3, до того, як ця таблиця була представлена у списку СПОЛУЧЕННЯ), і чорт важко помітити. Як щодо цього:
INSERT dbo.FinalTransaction
SELECT
newid() FinalTransactionGUID,
'GUID is: ' + Convert(varchar(50), FinalTransactionGUID) TextGUID,
T.*
FROM
dbo.MyTable T
На скільки ви хочете зробити ставку на те, що функцію newid () буде внесено в план виконання двічі, абсолютно несподівано зробивши два стовпці різними значеннями? Як щодо того, коли вищезазначений запит використовується N рівнів глибоко в CTE або похідних таблицях. Я гарантую, що проблема є гіршою, ніж ви можете собі уявити. Вже є серйозні проблеми з неузгодженістю з приводу того, коли речі оцінюються лише один раз або в який момент плану запитів, і Microsoft заявила, що це не виправитьдеякі з них тому, що вони належним чином виражають алгебру запитів - якщо ви отримаєте несподівані результати, розбийте запит на частини. Дозволити ланцюгові посилання, виявити кругові посилання через потенційно дуже довгі такі ланцюги - це досить складні проблеми. Введіть паралелізм, і у вас виник кошмар.
Примітка: Використання псевдоніму WHERE або GROUP BY не буде впливати на проблеми з такими функціями, як newid () або rand ().
Спосіб SQL Server для створення виразів для багаторазового використання
CROSS APPLY / OUTER APPLY - це один із способів у SQL Server для створення виразів, які можна використовувати будь-де в запиті (тільки не раніше у пункті ВІД):
SELECT
X.CalcID
FROM
Table1 T
INNER JOIN Table3 T3
ON T.ID = T3.ID
CROSS APPLY (
SELECT
T3.ID + (SELECT Min(Interval) FROM Intervals WHERE IntName = 'T') CalcID
) X
INNER JOIN Table2 T2
ON T2.ID = X.CalcID
Це робить дві речі:
- Робить усі вирази в CROSS APPLY отримати "простір імен" (псевдонім таблиці, тут, X) і бути унікальним у цьому просторі імен.
- Повсюдно стає очевидним не лише те, що CalcID походить від X, але й робить очевидним, чому ви не можете використовувати нічого з X при приєднанні до таблиць T1 і T3, оскільки X ще не представлено.
Я насправді дуже люблю CROSS APPLY. Це стало моїм вірним другом, і я ним постійно користуюся. Потрібна часткова UNPIVOT (що вимагатиме PIVOT / UNPIVOT або UNPIVOT / PIVOT з використанням нативного синтаксису)? Зроблено з CROSS APPLY. Потрібно розрахункове значення, яке буде повторно використане багато разів Зроблено. Потрібно жорстко виконувати порядок виконання дзвінків через пов'язаний сервер? Зроблено - з кричущим покращенням швидкості. Вам потрібен лише один тип рядків, розділених на 2 ряди або з додатковими умовами? Зроблено.
Отже, щонайменше, у СУБД SQL Server 2005 та новіших версій у вас більше не виникає причин для скарг: CROSS APPLY - це те, як ви ДУХИТЕ так, як вам хочеться.