如何从多个SQL SELECTS加入聚合结果?

时间:2009-08-08 13:42:53

标签: sql sql-server join group-by

我有一个MEMBERS表,其中包含以下相关列:

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

我想创建一个查询来返回一个成员资格摘要,其中列出了按年份和成员资格级别加入的总人数。基本上,我的结果集中的列将是这样的:

| YEAR | GOLD | SILVER | BRONZE | TOTAL |

我可以使用以下3个查询分别获得Gold,Silver和Bronze成员每年的不同计数:

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)  

我也可以使用类似的查询获得总数:

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

我的问题是我还没有找到将所有这些简化为单个查询的方法。这是怎么做到的?

3 个答案:

答案 0 :(得分:3)

您正在寻找所谓的交叉表查询或数据透视表。

这应该为你做.. ..

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)

有关交叉表查询的更多信息here

答案 1 :(得分:1)

最简单的方法是:

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)

答案 2 :(得分:1)

要将总数添加到Juliet的答案中,只需添加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)