Anticipata (o ri-ordinato) il riutilizzo di colonne derivate in una query - è questa valida ANSI SQL?
-
20-09-2019 - |
Domanda
E 'questo valido ANSI SQL:?
SELECT 1 AS X
,2 * X AS Y
,3 * Y AS Z
A causa Teradata (12) può fare questo, così come questo (sì, pazzo non è vero):
SELECT 3 * Y AS Z
,2 * X AS Y
,1 AS X
Ma SQL Server 2005 richiede qualcosa di simile:
SELECT X
,Y
,3 * Y AS Z
FROM (
SELECT X
,2 * X AS Y
FROM (
SELECT 1 AS X
) AS X
) AS Y
Soluzione
No, non è ANSI valido. ANSI presuppone che tutti gli elementi clausola SELECT vengono valutate in una sola volta.
E I'd've scritto in SQL 2005 come:
SELECT *
FROM (SELECT 1 AS X) X
CROSS APPLY (SELECT 2 * X AS Y) Y
CROSS APPLY (SELECT 3 * Y AS Z) Z
;
Altri suggerimenti
Non ha bisogno di essere quel brutto in SQL Server 2005 +. È per questo che Microsoft ha introdotto 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
Oppure si potrebbe usare CROSS APPLY
come dimostra Rob -. Che possono o non possono lavorare per voi a seconda delle specifiche della query
Ammetto che non è pulita come Teradata di, ma non è così male come la versione subquery, e l'esempio originale Teradata nella tua domanda non è sicuramente parte dello standard SQL-92.
Vorrei anche aggiungere che nel tuo esempio originale, il X
, Y
e colonne Z
non sono, tecnicamente, colonne derivate come li chiami tu. Almeno per quanto riguarda Microsoft e ANSI, questi ultimi sono solo alias , e un alias non possono fare riferimento a un altro alias fino a diventare in realtà una colonna (ad esempio tramite una sottoquery o CTE).