zoukankan      html  css  js  c++  java
  • SQLSERVER 使用 ROLLUP 汇总数据,实现分组统计,合计,小计

    表结构:

    CREATE TABLE [dbo].[Students](
        [ID] [int] IDENTITY(1,1) NOT NULL,
        [StudentName] [nvarchar](50) NULL,
        [Sex] [int] NOT NULL,
        [GradeName] [nvarchar](50) NULL,
        [ClassName] [nvarchar](50) NULL,
        [BodyWeight] [decimal](18, 2) NOT NULL,
        [Area] [nvarchar](50) NULL,
     CONSTRAINT [PK_Students] PRIMARY KEY CLUSTERED 
    (
        [ID] ASC
    )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    

    测试数据:

    INSERT [dbo].[Students] ([ID], [StudentName], [Sex], [GradeName], [ClassName], [BodyWeight], [Area]) VALUES (1, N'张三', 1, N'高一', N'1班', CAST(140.00 AS Decimal(18, 2)), N'中国')
    INSERT [dbo].[Students] ([ID], [StudentName], [Sex], [GradeName], [ClassName], [BodyWeight], [Area]) VALUES (2, N'李四', 1, N'高一', N'1班', CAST(140.00 AS Decimal(18, 2)), N'中国')
    INSERT [dbo].[Students] ([ID], [StudentName], [Sex], [GradeName], [ClassName], [BodyWeight], [Area]) VALUES (3, N'王五', 1, N'高一', N'1班', CAST(155.00 AS Decimal(18, 2)), N'中国')
    INSERT [dbo].[Students] ([ID], [StudentName], [Sex], [GradeName], [ClassName], [BodyWeight], [Area]) VALUES (4, N'奥巴马', 1, N'高一', N'2班', CAST(138.00 AS Decimal(18, 2)), N'美国')
    INSERT [dbo].[Students] ([ID], [StudentName], [Sex], [GradeName], [ClassName], [BodyWeight], [Area]) VALUES (5, N'希拉里', 0, N'高一', N'2班', CAST(113.00 AS Decimal(18, 2)), N'美国')
    INSERT [dbo].[Students] ([ID], [StudentName], [Sex], [GradeName], [ClassName], [BodyWeight], [Area]) VALUES (6, N'习XX', 1, N'高一', N'1班', CAST(110.00 AS Decimal(18, 2)), N'中国')
    INSERT [dbo].[Students] ([ID], [StudentName], [Sex], [GradeName], [ClassName], [BodyWeight], [Area]) VALUES (7, N'温宝宝', 1, N'高一', N'1班', CAST(200.00 AS Decimal(18, 2)), N'中国')
    INSERT [dbo].[Students] ([ID], [StudentName], [Sex], [GradeName], [ClassName], [BodyWeight], [Area]) VALUES (8, N'埃希', 0, N'高一', N'1班', CAST(123.00 AS Decimal(18, 2)), N'澳大利亚')
    INSERT [dbo].[Students] ([ID], [StudentName], [Sex], [GradeName], [ClassName], [BodyWeight], [Area]) VALUES (9, N'卡特琳娜', 0, N'高二', N'1班', CAST(145.00 AS Decimal(18, 2)), N'澳大利亚')
    INSERT [dbo].[Students] ([ID], [StudentName], [Sex], [GradeName], [ClassName], [BodyWeight], [Area]) VALUES (10, N'德玛西亚', 1, N'高二', N'2班', CAST(90.00 AS Decimal(18, 2)), N'英国')
    INSERT [dbo].[Students] ([ID], [StudentName], [Sex], [GradeName], [ClassName], [BodyWeight], [Area]) VALUES (11, N'嘉文', 1, N'高二', N'2班', CAST(95.00 AS Decimal(18, 2)), N'英国')
    INSERT [dbo].[Students] ([ID], [StudentName], [Sex], [GradeName], [ClassName], [BodyWeight], [Area]) VALUES (12, N'德邦', 1, N'高二', N'2班', CAST(102.00 AS Decimal(18, 2)), N'英国')
    INSERT [dbo].[Students] ([ID], [StudentName], [Sex], [GradeName], [ClassName], [BodyWeight], [Area]) VALUES (13, N'蛮子', 1, N'高三', N'1班', CAST(160.00 AS Decimal(18, 2)), N'刚果')
    INSERT [dbo].[Students] ([ID], [StudentName], [Sex], [GradeName], [ClassName], [BodyWeight], [Area]) VALUES (14, N'易大师', 1, N'高三', N'1班', CAST(120.00 AS Decimal(18, 2)), N'刚果')

    情况一:只有一个分类统计列,只需要一个合计。只需要增加with rollup即可。

     

    SELECT CASE WHEN GROUPING(GradeName)=1 THEN '合计' ELSE GradeName END AS 年级 ,
          SUM(CASE WHEN Sex=1 THEN 1 ELSE 0 END) AS 男生数,
          SUM(CASE WHEN Sex=0 THEN 1 ELSE 0 END) AS 女生数,
          COUNT(Sex) AS 总数
    FROM dbo.Students
    GROUP BY GradeName WITH ROLLUP
    ORDER BY GradeName DESC

    情况二:有多个分类汇总列,只需要一个合计。增加rollup之后,需要使用GROUPING函数判断。

    GROUPING函数 指示是否聚合 GROUP BY 列表中的指定列表达式。 在结果集中,如果 GROUPING 返回 1 则指示聚合;返回 0 则指示不聚合。 如果指定了 GROUP BY,则 GROUPING 只能用在 SELECT <select> 列表、HAVING 和 ORDER BY 子句中。

    SELECT CASE WHEN GROUPING(GradeName)=1 THEN '合计' ELSE GradeName END AS 年级 ,
            ClassName AS 班级 ,
          SUM(CASE WHEN Sex=1 THEN 1 ELSE 0 END) AS 男生数,
          SUM(CASE WHEN Sex=0 THEN 1 ELSE 0 END) AS 女生数,
          COUNT(Sex) AS 总数
    FROM dbo.Students
    GROUP BY GradeName,ClassName WITH ROLLUP
    HAVING GROUPING(GradeName)=1 OR GROUPING(ClassName)=0
    ORDER BY GradeName DESC

    SELECT CASE WHEN GROUPING(GradeName)=1 THEN '合计' ELSE GradeName END AS 年级 ,
           ClassName AS 班级 ,
           Area AS 地区 ,
          SUM(CASE WHEN Sex=1 THEN 1 ELSE 0 END) AS 男生数,
          SUM(CASE WHEN Sex=0 THEN 1 ELSE 0 END) AS 女生数,
          COUNT(Sex) AS 总数
    FROM dbo.Students
    GROUP BY GradeName,ClassName,Area WITH ROLLUP
    HAVING GROUPING(GradeName)=1 OR (GROUPING(ClassName)=0 AND GROUPING(Area) =0)
    ORDER BY GradeName DESC

     情况三:有多个分类汇总列,需要显示全部的合计和小计。不需要增加判断。

     

    SELECT CASE WHEN GROUPING(GradeName)=1 THEN '合计' ELSE GradeName END AS 年级 ,
           CASE WHEN GROUPING(GradeName)=0 AND GROUPING(ClassName)=1 THEN '小计' ELSE ClassName END AS 班级 ,
          SUM(CASE WHEN Sex=1 THEN 1 ELSE 0 END) AS 男生数,
          SUM(CASE WHEN Sex=0 THEN 1 ELSE 0 END) AS 女生数,
          COUNT(Sex) AS 总数
    FROM dbo.Students
    GROUP BY GradeName,ClassName WITH ROLLUP
    ORDER BY GradeName DESC

    情况四:有多个分类汇总列,需要显示部分的合计和小计。增加rollup之后,需要增加判断

    SELECT CASE WHEN GROUPING(GradeName)=1 THEN '年级合计' ELSE GradeName END AS 年级 ,
           CASE WHEN GROUPING(GradeName)=0 AND GROUPING(ClassName)=1 THEN '班级小计' ELSE ClassName END AS 班级 ,
           CASE WHEN GROUPING(ClassName)=0 AND GROUPING(Area)=1 THEN '地区小计' ELSE Area END AS 地区 ,
          SUM(CASE WHEN Sex=1 THEN 1 ELSE 0 END) AS 男生数,
          SUM(CASE WHEN Sex=0 THEN 1 ELSE 0 END) AS 女生数,
          COUNT(Sex) AS 总数,
          GROUPING(GradeName) AS GradeName_G,
          GROUPING(ClassName) AS ClassName_G,
          GROUPING(Area) AS Area_G
    FROM dbo.Students
    GROUP BY GradeName,ClassName,Area WITH ROLLUP
    HAVING GROUPING(GradeName)=1 OR GROUPING(Area)=0 OR GROUPING(ClassName)=0
    ORDER BY GradeName DESC
  • 相关阅读:
    linux同一客户端多个git账号的配置
    linux同一台机子上用多个git 账号
    执行ssh-add时出现Could not open a connection to your authentication agent
    国内常用NTP服务器地址及IP
    PHP双引号的隐患
    mysql 累加求和
    php实现Facebook风格的 time ago函数
    Mysql之数据库设计规范
    搭建Git服务器
    win7下如何根据端口号杀掉进程
  • 原文地址:https://www.cnblogs.com/xiaohuhu/p/14384157.html
Copyright © 2011-2022 走看看