Как мне присоединиться к результатам агрегации из нескольких SQL SELECTS? - PullRequest
1 голос
/ 08 августа 2009

У меня есть таблица MEMBERS со следующими соответствующими столбцами:

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

Я хочу создать один запрос для возврата сводной информации о членстве, в которой указано общее число присоединившихся по годам и уровню членства По сути, столбцы в моем наборе результатов будут выглядеть примерно так:

| YEAR | GOLD | SILVER | BRONZE | TOTAL |

Я мог бы получать разные значения в год для участников уровня Gold, Silver и Bronze соответственно, используя следующие 3 запроса:

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 ]

3 голосов
/ 08 августа 2009

Вы ищете так называемый перекрестный запрос или сводную таблицу.

Это должно сделать это для вас ..

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)

Подробнее о перекрестных запросах здесь .

1 голос
/ 08 августа 2009

И чтобы добавить итог к ответу Джульетты, просто добавьте 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)
1 голос
/ 08 августа 2009

Самый простой способ будет:

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)
...