6

这是有效的 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
4

2 回答 2

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
;
于 2010-03-17T02:20:22.747 回答
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列在技术上不是您所称的派生列。至少就 Microsoft 和 ANSI 而言,它们只是aliases,并且一个 alias 不能引用另一个别名,直到它真正成为一个列(即通过子查询或 CTE)。

于 2010-03-17T02:33:19.687 回答