带有摘要数据的SQL Pivot查询

时间:2016-08-09 17:20:19

标签: sql-server pivot

我无法理解如何进行此数据透视查询。我尝试了几种变化,但我一直都有错误!

我有这些数据:

ID    OfficerAge    CitizenAge
1       35             21
2       36             33
3       22             18

我可以轻松获得每个人的年龄组,但我想要一个矩阵:

Officer/Citizen:   Under 19   20-29   30-39
Under 19           0          0       0
20-29              1          0       0
30-39              0          1       1

我非常感谢您正确构建查询的任何帮助!!

谢谢!

1 个答案:

答案 0 :(得分:2)

使用聚合构建查询:

select (case when officerage < 19 then 'Under 19'
             when officerage < 30 then '19-29'
             when officerage < 40 then '30-39'
             else 'old!'
        end) as officeragegrp,
       sum(case when citizenage < 19 then 1 else 0 end) as [Under 19],
       sum(case when citizenage >= 19 and citizenage < 30 then 1 else 0 end) as [19-29],
       sum(case when citizenage >= 30 and citizenage < 40 then 1 else 0 end) as [30-39],
       sum(case when citizenage > 39 then 1 else 0 end) as [Old!]
from t
group by (case when officerage < 19 then 'Under 19'
               when officerage < 30 then '19-29'
               when officerage < 40 then '30-39'
               else 'old!'
          end)
order by min(officerage);

编辑:

如果您需要包含不存在的群组,那么left join会有所帮助:

select officeragegroupp,
       sum(case when citizenage < 19 then 1 else 0 end) as [Under 19],
       sum(case when citizenage >= 19 and citizenage < 30 then 1 else 0 end) as [19-29],
       sum(case when citizenage >= 30 and citizenage < 40 then 1 else 0 end) as [30-39],
       sum(case when citizenage > 39 then 1 else 0 end) as [Old!]
from (select 'Under 19' as officeragegroup union all
      select '19-29' union all
      select '30-39' union all
      select 'old!'
     ) oag left join
     (select t.*,
             (case when officerage < 19 then 'Under 19'
                   when officerage < 30 then '19-29'
                   when officerage < 40 then '30-39'
                   else 'old!'
              end) as officeragegroup
      from t
     ) t
     on t.officeragegroup = oag.officeragegroup
group by oag.officeragegroup
order by min(t.officerage);