Раннее (или переупорядоченное) повторное использование производных столбцов в запросе - это допустимый ANSI SQL? - PullRequest
6 голосов
/ 17 марта 2010

Это действительный ANSI SQL?:

SELECT 1 AS X
       ,2 * X AS Y
       ,3 * Y AS Z

Поскольку Teradata (12) может делать это, а также это (да, безумие, не правда ли):

SELECT 3 * Y AS Z
       ,2 * X AS Y
       ,1 AS X

Но для SQL Server 2005 требуется что-то вроде этого:

SELECT  X
       ,Y
       ,3 * Y AS Z
FROM    (
         SELECT X
               ,2 * X AS Y
         FROM   (
                 SELECT 1 AS X
                ) AS X
        ) AS Y

Ответы [ 2 ]

5 голосов
/ 17 марта 2010

Нет, это недействительно ANSI. ANSI предполагает, что все элементы предложения SELECT оцениваются одновременно.

И я написал бы это в SQL 2005 как:

SELECT *
FROM        (SELECT 1 AS X) X
CROSS APPLY (SELECT 2 * X AS Y) Y
CROSS APPLY (SELECT 3 * Y AS Z) Z
;
2 голосов
/ 17 марта 2010

Это не должно быть так ужасно в SQL Server 2005+. Вот почему Microsoft представила CTE:

WITH T1 AS (SELECT 1 AS X),
     T2 AS (SELECT X, 2 * X AS Y FROM T1)
SELECT X, Y, 3 * Y AS Z FROM T2

Или вы можете использовать CROSS APPLY, как показывает Роб - это может работать, а может и не работать, в зависимости от специфики запроса.

Я признаю, что он не такой чистый, как у Teradata, но он не так плох, как версия подзапроса, и оригинальный пример Teradata в вашем вопросе определенно не является частью стандарта SQL-92.

Я бы также добавил, что в вашем исходном примере столбцы X, Y и Z не являются технически производными столбцами , как вы их называете. По крайней мере, в том, что касается Microsoft и ANSI, они являются просто псевдонимами , и псевдоним не может ссылаться на другой псевдоним, пока он фактически не станет столбцом (т.е. через подзапрос или CTE).

...