2010-03-16 10 views
6

Ist das gültige ANSI SQL ?:Frühzeitige (oder nachgeordnete) Wiederverwendung von abgeleiteten Spalten in einer Abfrage - ist dies gültige ANSI SQL?

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

Da Teradata (12) dies tun kann, als auch der (ja, verrückt ist es nicht):

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

Aber SQL Server 2005 erfordert etwa Folgendes:

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

Ich frage mich, welchen Fehler es wirft, wenn Sie versuchen, SELECT 2 * y AS x, 2 * x AS y ' –

Antwort

5

Nein, es ist nicht gültig ANSI. ANSI geht davon aus, dass alle Elemente der SELECT-Klausel gleichzeitig ausgewertet werden.

Und I'd've es in SQL 2005 geschrieben als:

SELECT * 
FROM  (SELECT 1 AS X) X 
CROSS APPLY (SELECT 2 * X AS Y) Y 
CROSS APPLY (SELECT 3 * Y AS Z) Z 
; 
+1

Eine clevere Alternative zu den CTEs - Ich werde das im Hinterkopf behalten. Leider unterstützt Teradata weder gestapelte CTEs (ich glaube, es unterstützt einen, also ist das auf meiner Liste zu untersuchen) noch der APPLY-Operator. –

+0

Natürlich ist die Wiederverwendung von Aliasen in Teradata nicht ANSI SQL, aber CROSS APPLY ist auch eine Erweiterung zu Standard SQL :-) – dnoeth

2

Es ist nicht in SQL Server 2005+, dass hässlich sein müssen. Deshalb Microsoft CTE eingeführt:

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 

Oder könnten Sie CROSS APPLY verwenden, wie Rob demonstriert - die nicht funktionieren kann oder auch für Sie auf die Besonderheiten der Abfrage abhängig.

Ich gebe zu, dass es nicht so sauber wie Teradata ist, aber es ist nicht annähernd so schlimm wie die Unterabfrage-Version, und das ursprüngliche Teradata Beispiel in Ihrer Frage ist definitiv nicht Teil des SQL-92-Standards.

Ich würde auch, dass in Ihrem ursprünglichen Beispiel hinzufügen, die X, Y und Z Spalten sind nicht technisch abgeleiteten Spalten, wie Sie sie nennen. Zumindest so weit wie Microsoft und ANSI betroffen sind, sind sie nur Aliase, und ein Alias ​​kann nicht auf einen anderen Alias ​​verweisen, bis es tatsächlich eine Spalte wird (d. H. Durch eine Unterabfrage oder CTE).

+0

Wir verwenden normalerweise mehrere gestapelte CTEs in SQL Server. Leider sind sie in Teradata nicht erlaubt ;-(Ich versuche einen Mittelweg zu finden. Was ich finde, ist, dass Teradata viel besser funktioniert, wenn du nicht nestest, und benutze diesen Trick, aber das beunruhigt mich es könnte nicht weiter funktionieren und ich wäre besser dran gewesen, meine CTEs in Nesting umgewandelt zu haben, wenn das in Teradata in Zukunft bricht. –