245 votes

Rester simple et comment faire plusieurs CTE dans une requête

J'ai cette requête T-SQL simple, qui émet un ensemble de colonnes à partir d'une table et joint également des informations provenant d'autres tables. apparenté tables.

Mon modèle de données est simple. J'ai un événement programmé, avec des participants. J'ai besoin de connaître le nombre de participants à chaque événement.

Ma solution consiste à ajouter un CTE qui regroupe les événements programmés et compte le nombre de participants.

Cela me permettra de joindre ces informations par événement programmé. La requête doit rester simple.

J'aime que mes requêtes soient simples, mais si je dois à l'avenir avoir accès à des résultats temporaires supplémentaires lors de ma requête simple, que dois-je faire ?

J'aimerais vraiment pouvoir avoir plusieurs CTE, mais ce n'est pas possible, n'est-ce pas ? Quelles sont mes options ?

J'ai exclu les vues et les actions au niveau de la couche de données de l'application. Je préfère isoler mes requêtes SQL.

458voto

Quassnoi Points 191041

Vous pouvez avoir plusieurs CTE en une seule requête, ainsi que la réutilisation d'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

Il convient toutefois de noter que SQL Server peut réévaluer la CTE à chaque fois qu'on y accède, donc si vous utilisez des valeurs comme RAND() , NEWID() etc., ils peuvent changer entre les CTE appels.

129voto

Randy Minder Points 19262

Il est tout à fait possible d'avoir plusieurs CTE dans une seule expression de requête. Il suffit de les séparer par une virgule. Voici un exemple. Dans l'exemple ci-dessous, il y a deux CTE. L'un s'appelle CategoryAndNumberOfProducts et le second s'appelle 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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X