Come posso avere più espressioni di tabella comuni in una singola istruzione SELECT?


93

Sto semplificando un'istruzione select complicata, quindi ho pensato di utilizzare espressioni di tabella comuni.

Dichiarare un singolo cte funziona bene.

WITH cte1 AS (
    SELECT * from cdr.Location
    )

select * from cte1 

È possibile dichiarare e utilizzare più di un cte nella stessa SELECT?

cioè questo sql dà un errore

WITH cte1 as (
    SELECT * from cdr.Location
)

WITH cte2 as (
    SELECT * from cdr.Location
)

select * from cte1    
union     
select * from cte2

l'errore è

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. Ho provato a inserire i punti e virgola e ottengo questo errore

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

Probabilmente non è rilevante, ma questo è su SQL 2008.

Risposte:


140

Penso che dovrebbe essere qualcosa del tipo:

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

Fondamentalmente, qui WITHè solo una clausola e, come le altre clausole che accettano elenchi, "," è il delimitatore appropriato.


È fantastico. Stavo riempiendo le tabelle temporanee con i risultati del CTE e combinando in seguito, ma ho riscontrato problemi con i punti e virgola durante il confezionamento in una procedura memorizzata. Bel metodo!
Tom Halladay

18
Non dimenticare che cte2può fare riferimento in questo cte1modo: ... cte2 as (SELECT * FROM cte1 WHERE ...)
Chahk

Eroe! Questo mi ha lasciato perplesso per ore
bjpelcdev

2
che dire della dichiarazione di espressioni ricorsive e non ricorsive?
Dmitry Volkov

15

La risposta sopra menzionata è giusta:

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

Inoltre, puoi anche eseguire una query da cte1 in cte2:

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

select * from cte1 union select * from cte2

val1,val2 sono solo supposizioni per le espressioni ..

Spero che questo blog possa aiutare anche: http://iamfixed.blogspot.de/2017/11/common-table-expression-in-sql-with.html


che dire della dichiarazione di espressioni ricorsive e non ricorsive?
Dmitry Volkov
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.