Houd het simpel en doe meerdere CTE’s in een query

Ik heb deze eenvoudige T-SQL-query, deze zendt een aantal kolommen uit een tabel uit en voegt ook informatie samen uit andere gerelateerdetabellen.

Mijn gegevensmodel is eenvoudig. Ik heb een gepland evenement, met deelnemers. Ik moet weten hoeveel deelnemers aan elk evenement deelnemen.

Mijn oplossing hiervoor is om een CTE toe te voegen die geplande evenementen groepeert en het aantal deelnemers telt.

Hierdoor kan ik deelnemen aan die informatie per geplande gebeurtenis. De vraag eenvoudig houden.

Ik houd mijn zoekopdrachten graag eenvoudig, maar als ik in de toekomst aanvullende tijdelijke resultaten nodig heb tijdens mijn eenvoudige zoekopdracht, wat moet ik dan doen?

Ik zou het heel leuk vinden als ik meerdere CTE’s zou kunnen hebben, maar dat kan niet, toch? Wat zijn mijn opties hier?

Ik heb weergaven en dingen op de applicatiegegevenslaag uitgesloten. Ik geef er de voorkeur aan om mijn SQL-query’s te isoleren.


Antwoord 1, autoriteit 100%

U kunt meerdere CTE‘s in één zoekopdracht hebben en een CTEopnieuw gebruiken:

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

Houd er echter rekening mee dat SQL Serverde CTEelke keer dat deze wordt geopend opnieuw kan evalueren, dus als u waarden gebruikt zoals RAND(), NEWID()enz., ze kunnen wisselen tussen de CTE-aanroepen.


Antwoord 2, autoriteit 29%

U kunt zeker meerdere CTE’s in één query-expressie hebben. Je hoeft ze alleen maar te scheiden met een komma. Hier is een voorbeeld. In het onderstaande voorbeeld zijn er twee CTE’s. De ene heet CategoryAndNumberOfProductsen de tweede heet 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

Other episodes