2010-01-26 10 views
79

Ho questa semplice query T-SQL, emette un sacco di colonne da una tabella e unisce anche le informazioni di altre tabelle correlate a.Mantenerlo semplice e come eseguire più CTE in una query

Il mio modello di dati è semplice. Ho un evento programmato, con partecipanti. Devo sapere quanti partecipanti partecipano a ciascun evento.

La mia soluzione è aggiungere un CTE che raggruppa eventi pianificati e conta il numero di partecipanti.

Questo mi consentirà di partecipare a tali informazioni per evento programmato. Mantenere la query semplice.

Mi piace mantenere le mie domande semplici, tuttavia, se mai dovessi avere in futuro risultati temporanei aggiuntivi accessibili durante la mia semplice query, cosa devo fare?

Mi piacerebbe molto, se potessi avere più CTE ma non posso, giusto? quali sono le mie opzioni?

Ho escluso le viste e faccio le cose a livello di dati dell'applicazione. Preferisco isolare le mie query SQL.

risposta

158

è possibile avere più CTE s in una query, nonché il riutilizzo di un CTE:

WITH cte1 AS 
     (
     SELECT 1 AS id 
     ), 
     cte2 AS 
     (
     SELECT 2 AS id 
     ) 
SELECT * 
FROM cte1 
UNION ALL 
SELECT * 
FROM cte2 
UNION ALL 
SELECT * 
FROM cte1 

Si noti, tuttavia, che SQL Server può rivalutare il CTE ogni volta che si accede, quindi se si sta utilizzando i valori come RAND(), NEWID() ecc., possono cambiare tra le chiamate CTE.

+1

Era così semplice. la documentazione MSDN era un po 'confusa sul problema, non ho trovato nulla di conclusivo. Grazie mille! –

+1

È documentato in [WITH common_table_expression (Transact-SQL)] (http://msdn.microsoft.com/en-us/library/ms175972.aspx). Puoi vedere che questo è nella sezione della sintassi (prendi nota in particolare di '[, ... n]' in '[WITH [, ... n]]'. Esempio C, "Uso di più definizioni CTE in una singola query, "lo chiama esplicitamente. Purtroppo questo esempio non è fornito nella documentazione per SQL 2008 e precedenti (ovvero, l'esempio non è stato fornito quando l'OP ha pubblicato la domanda) – Brian

51

È certamente possibile disporre di più CTE in una singola espressione di query. Hai solo bisogno di separarli con una virgola. Ecco un esempio. Nell'esempio seguente, ci sono due CTE. Uno è denominato CategoryAndNumberOfProducts e il secondo è denominato ProductsOverTenDollars.

WITH CategoryAndNumberOfProducts (CategoryID, CategoryName, NumberOfProducts) AS 
(
    SELECT 
     CategoryID, 
     CategoryName, 
     (SELECT COUNT(1) FROM Products p 
     WHERE p.CategoryID = c.CategoryID) as NumberOfProducts 
    FROM Categories c 
), 

ProductsOverTenDollars (ProductID, CategoryID, ProductName, UnitPrice) AS 
(
    SELECT 
     ProductID, 
     CategoryID, 
     ProductName, 
     UnitPrice 
    FROM Products p 
    WHERE UnitPrice > 10.0 
) 

SELECT c.CategoryName, c.NumberOfProducts, 
     p.ProductName, p.UnitPrice 
FROM ProductsOverTenDollars p 
    INNER JOIN CategoryAndNumberOfProducts c ON 
     p.CategoryID = c.CategoryID 
ORDER BY ProductName 
+2

@JohnLeidegren: postare una risposta corretta entro 2 minuti dalla prima risposta corretta merita un upvote, che ho dato, almeno –

+0

Che commento inutile. "SO (stackoverflow) è abbastanza pesantemente moderato" - e per fortuna questo ragazzo non è uno dei moderatori. –