2010-01-26 5 views
79

Ich habe diese einfache T-SQL-Abfrage, es emittiert eine Reihe von Spalten aus einer Tabelle und verbindet auch Informationen aus anderen bezogenen Tabellen.Keeping es einfach und wie mehrere CTE in einer Abfrage zu tun

Mein Datenmodell ist einfach. Ich habe eine geplante Veranstaltung mit Teilnehmern. Ich muss wissen, wie viele Teilnehmer an jeder Veranstaltung teilnehmen.

Meine Lösung ist das Hinzufügen eines CTE, der geplante Ereignisse gruppiert und die Anzahl der Teilnehmer zählt.

Dies ermöglicht es mir, diese Informationen pro geplantem Ereignis beizutreten. Halten Sie die Abfrage einfach.

Ich mag es, meine Abfragen einfach zu halten, aber wenn ich jemals in der Zukunft zusätzliche temporäre Ergebnisse während meiner einfachen Abfrage zugänglich machen muss, was soll ich tun?

Ich würde es wirklich gerne, wenn ich mehrere CTEs haben könnte, aber ich kann nicht, oder? Was sind meine Möglichkeiten hier?

Ich habe Ansichten und Dinge auf der Anwendungsdatenebene ausgeschlossen. Ich bevorzuge es, meine SQL-Abfragen zu isolieren.

Antwort

158

können Sie haben mehrere CTE s in einer Abfrage sowie die Wiederverwendung eines 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 

Beachten Sie jedoch, dass SQL Server die CTE jedes Mal neu bewerten kann es zugegriffen wird, so dass, wenn Sie Werte verwenden wie RAND(), NEWID() usw., können sie zwischen den CTE Anrufe wechseln.

+1

Es war so einfach. Die MSDN-Dokumentation war ein wenig unscharf um das Problem, ich konnte nichts Schlüssiges finden. Vielen Dank! –

+1

Es ist dokumentiert in [MIT common_table_expression (Transact-SQL)] (http://msdn.microsoft.com/en-us/library/ms175972.aspx). Sie können sehen, dass dies im Syntaxbereich ist (beachten Sie besonders die '[, ... n]' in '[WITH [, ... n]]'. Beispiel C, "Verwenden mehrerer CTE-Definitionen in eine einzelne Abfrage "ruft dies explizit auf. Leider ist dieses Beispiel nicht in der Dokumentation für SQL 2008 und älter enthalten (dh das Beispiel wurde nicht zur Verfügung gestellt, als das OP die Frage gestellt hat). – Brian

51

Sie können sicherlich mehrere CTEs in einem einzigen Abfrageausdruck haben. Sie müssen sie nur durch ein Komma trennen. Hier ist ein Beispiel. Im folgenden Beispiel gibt es zwei CTEs. Eine heißt CategoryAndNumberOfProducts und die zweite heißt 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: eine korrekte Antwort posten innerhalb von 2 Minuten nach der ersten richtigen Antwort verdient ein Upvote, den ich zumindest gegeben habe .. –

+0

Was für ein sinnloser Kommentar. "SO (stackoverflow) wird ziemlich stark moderiert" - und zum Glück ist dieser Typ keiner der Moderatoren. –