2009-08-08 4 views
1

J'ai une table MEMBERS avec les colonnes pertinentes suivantes:Comment joindre les résultats d'agrégation de plusieurs SQL SELECTS?

Name 
JoinDate 
Level --1=Gold,2=Silver,3=Bronze** 

Je veux créer une seule requête pour renvoyer un résumé d'adhésion qui indique le nombre total qui se sont joints par année et par niveau d'adhésion. Au fond, les colonnes de mon resultset serait quelque chose comme ceci:

| YEAR | GOLD | SILVER | BRONZE | TOTAL | 

je pouvais obtenir les différents chefs d'accusation par an pour l'or, les membres d'argent et de bronze en utilisant respectivement les 3 requêtes suivantes:

SELECT YEAR(JoinDate) AS YEAR, COUNT(*) AS GOLD FROM Members 
WHERE Level=1 GROUP BY YEAR(JoinDate) ORDER BY YEAR(JoinDate) 

SELECT YEAR(JoinDate) AS YEAR, COUNT(*) AS SILVER FROM Members 
WHERE Level=2 GROUP BY YEAR(JoinDate) ORDER BY YEAR(JoinDate) 

SELECT YEAR(JoinDate) AS YEAR, COUNT(*) AS BRONZE FROM Members 
WHERE Level=3 GROUP BY YEAR(JoinDate) ORDER BY YEAR(JoinDate) 

I pourrait également obtenir les totaux en utilisant une requête similaire:

SELECT YEAR(JoinDate) AS YEAR, COUNT(*) AS TOTAL FROM Members 
GROUP BY YEAR(JoinDate) ORDER BY YEAR(JoinDate) 

Mon problème est que je ne l'ai pas trouvé un moyen de simplifier tout cela en une seule requête. Comment cela est-il fait?

Répondre

3

Vous êtes à la recherche de ce que l'on appelle une requête croisée onglet ou tableau croisé dynamique.

Cela devrait le faire pour vous ..

SELECT  YEAR(JoinDate) YEAR, 
      SUM(CASE [Level] WHEN 1 THEN 
        1 ELSE 0 END) Gold, 
      SUM(CASE [Level] WHEN 2 THEN 
        1 ELSE 0 END) Silver, 
      SUM(CASE [Level] WHEN 3 THEN 
        1 ELSE 0 END) Bronze, 
     COUNT([Level]) Total 
FROM  members 
GROUP BY YEAR(JoinDate) 
ORDER BY YEAR(JoinDate) 

Plus sur les requêtes cross-tab here.

1

façon simple serait:

SELECT YEAR(JoinDate) AS YEAR, 
    SUM(case when Level = 1 then 1 else 0 end) AS GoldCount, 
    SUM(case when Level = 2 then 1 else 0 end) AS SilverCount, 
    SUM(case when Level = 3 then 1 else 0 end) AS BronzeCount 
FROM Members 
GROUP BY YEAR(JoinDate) ORDER BY YEAR(JoinDate) 
1

Et pour ajouter le total à la réponse de Juliette, ajoutez simplement COUNT (*)

SELECT YEAR(JoinDate) AS YEAR,  
    SUM(case when Level = 1 then 1 else 0 end) AS GoldCount,  
    SUM(case when Level = 2 then 1 else 0 end) AS SilverCount,  
    SUM(case when Level = 3 then 1 else 0 end) AS BronzeCount, 
    Count(*) TotalCount 
FROM Members 
GROUP BY YEAR(JoinDate) 
ORDER BY YEAR(JoinDate) 
Questions connexes