Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Early (or re-ordered) re-use of derived columns in a query - is this valid ANSI SQL?

Is this valid ANSI SQL?:

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

Because Teradata (12) can do this, as well as this (yes, crazy isn't it):

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

But SQL Server 2005 requires something like this:

SELECT  X
       ,Y
       ,3 * Y AS Z
FROM    (
         SELECT X
               ,2 * X AS Y
         FROM   (
                 SELECT 1 AS X
                ) AS X
        ) AS Y
like image 359
Cade Roux Avatar asked Mar 16 '10 22:03

Cade Roux


People also ask

What are derived columns in SQL?

Derived columns let you move the processing of an expression from the target instance to the source instance. For example, you may have already defined an expression that concatenates the values of two source columns, FIRSTNAME and LASTNAME, and mapped this expression to a target column named called FULLNAME.

How do you add two columns in SSIS?

Derived Columns Grid Derived Column Name: Specify the derived column name. Derived Column: Select between <add new column> and <replace an existing column> options. Expression: Write the SSIS expression that produce the derived column. Data Type: This column is read-only and it shows the data type of the expression ...

What does as do in SQL?

The AS command is used to rename a column or table with an alias. An alias only exists for the duration of the query.


2 Answers

No, it's not valid ANSI. ANSI assumes that all SELECT clause items are evaluated at once.

And I'd've written it in SQL 2005 as:

SELECT *
FROM        (SELECT 1 AS X) X
CROSS APPLY (SELECT 2 * X AS Y) Y
CROSS APPLY (SELECT 3 * Y AS Z) Z
;
like image 99
Rob Farley Avatar answered Sep 23 '22 02:09

Rob Farley


It doesn't need to be that ugly in SQL Server 2005+. That's why Microsoft introduced CTEs:

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

Or you could use CROSS APPLY as Rob demonstrates - that may or may not work for you depending on the specifics of the query.

I admit that it's not as clean as Teradata's, but it's not nearly as bad as the subquery version, and the original Teradata example in your question is definitely not part of the SQL-92 standard.

I'd also add that in your original example, the X, Y and Z columns are not, technically, derived columns as you call them. At least as far as Microsoft and ANSI are concerned, they are just aliases, and an alias can't refer to another alias until it actually becomes a column (i.e. through a subquery or CTE).

like image 25
Aaronaught Avatar answered Sep 23 '22 02:09

Aaronaught