在查询中早期(或重新排序)重用派生列 - 这是有效的ANSI SQL吗?

时间:2010-03-16 22:45:25

标签: sql sql-server teradata ansi-sql

这是有效的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 个答案:

答案 0 :(得分:5)

不,它不是有效的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
;

答案 1 :(得分:2)

在SQL Server 2005+中不需要那么难看。这就是微软推出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作为Rob演示 - 根据查询的具体情况,这可能适用于您,也可能不适用。

我承认它不像Teradata那样干净,但它并不像子查询版本那么糟糕,而你问题中的原始Teradata示例绝对不是SQL-92标准的一部分。

我还要在原始示例中添加,XYZ列在技术上不是派生列他们。至少就微软和ANSI而言,它们只是别名,并且别名在实际变为列之前(即通过子查询或CTE)不能引用另一个别名。