Wie kann ich mehrere gemeinsame Tabellenausdrücke in einer einzigen SELECT-Anweisung haben?


92

Ich bin gerade dabei, eine komplizierte select-Anweisung zu vereinfachen, also dachte ich, ich würde allgemeine Tabellenausdrücke verwenden.

Das Deklarieren eines einzelnen cte funktioniert einwandfrei.

WITH cte1 AS (
    SELECT * from cdr.Location
    )

select * from cte1 

Ist es möglich, mehr als ein cte in derselben SELECT zu deklarieren und zu verwenden?

dh diese SQL gibt einen Fehler

WITH cte1 as (
    SELECT * from cdr.Location
)

WITH cte2 as (
    SELECT * from cdr.Location
)

select * from cte1    
union     
select * from cte2

Der Fehler ist

Msg 156, Level 15, State 1, Line 7
Incorrect syntax near the keyword 'WITH'.
Msg 319, Level 15, State 1, Line 7
Incorrect syntax near the keyword 'with'. If this statement is a common table expression, an xmlnamespaces clause or a change tracking context clause, the previous statement must be terminated with a semicolon.

NB. Ich habe versucht, Semikolons einzufügen und diesen Fehler zu erhalten

Msg 102, Level 15, State 1, Line 5
Incorrect syntax near ';'.
Msg 102, Level 15, State 1, Line 9
Incorrect syntax near ';'.

Wahrscheinlich nicht relevant, aber dies ist unter SQL 2008.

Antworten:


139

Ich denke, es sollte so etwas sein wie:

WITH 
    cte1 as (SELECT * from cdr.Location),
    cte2 as (SELECT * from cdr.Location)
select * from cte1 union select * from cte2

Grundsätzlich WITHist hier nur eine Klausel, und wie bei den anderen Klauseln, die Listen enthalten, ist "," das geeignete Trennzeichen.


Das ist großartig. Ich hatte temporäre Tabellen mit den Ergebnissen des CTE gefüllt und später kombiniert, hatte jedoch Probleme mit Semikolons beim Verpacken in einen gespeicherten Prozess. Schöne Methode!
Tom Halladay

18
Vergessen Sie nicht, dass cte2dies cte1wie folgt verweisen kann: ... cte2 as (SELECT * FROM cte1 WHERE ...)
Chahk

Held! Dies hat mich stundenlang
verblüfft

2
Was ist mit der Deklaration rekursiver und nicht rekursiver Ausdrücke?
Dmitry Volkov

14

Die oben genannte Antwort ist richtig:

WITH 
    cte1 as (SELECT * from cdr.Location),
    cte2 as (SELECT * from cdr.Location)
select * from cte1 union select * from cte2

Zusätzlich können Sie auch von cte1 in cte2 abfragen:

WITH 
    cte1 as (SELECT * from cdr.Location),
    cte2 as (SELECT * from cte1 where val1 = val2)

select * from cte1 union select * from cte2

val1,val2 sind nur Annahmen für Ausdrücke ..

Hoffe, dieser Blog wird auch helfen: http://iamfixed.blogspot.de/2017/11/common-table-expression-in-sql-with.html


Was ist mit der Deklaration rekursiver und nicht rekursiver Ausdrücke?
Dmitry Volkov
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.