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]

GO

 測試數據:

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
View Code

情況二:有多個分類匯總列,只需要一個合計。增加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
View Code

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
View Code

情況三:有多個分類匯總列,需要顯示全部的合計和小計。不需要增加判斷。

 

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
View Code

情況四:有多個分類匯總列,需要顯示部分的合計和小計。增加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

參考:

使用ROLLUP 匯總數據

GROUPING

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM