SQL Server 之 GROUP BY、GROUPING SETS、ROLLUP、CUBE

原文:SQL Server 之 GROUP BY、GROUPING SETS、ROLLUP、CUBE

1.创建表 Staff

CREATE TABLE [dbo].[Staff](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [Name] [varchar](50) NULL,
    [Sex] [varchar](50) NULL,
    [Department] [varchar](50) NULL,
    [Money] [int] NULL,
    [CreateDate] [datetime] NULL
) ON [PRIMARY]

GO

 

2.为Staff表填充数据

INSERT INTO [dbo].[Staff]([Name],[Sex],[Department],[Money],[CreateDate])
SELECT 'Name1','男','技术部',3000,'2011-11-12'
UNION ALL
SELECT 'Name2','男','工程部',4000,'2013-11-12'
UNION ALL
SELECT 'Name3','女','工程部',3000,'2013-11-12'
UNION ALL
SELECT 'Name4','女','技术部',5000,'2012-11-12'
UNION ALL
SELECT 'Name5','女','技术部',6000,'2011-11-12'
UNION ALL
SELECT 'Name6','女','技术部',4000,'2013-11-12'
UNION ALL
SELECT 'Name7','女','技术部',5000,'2012-11-12'
UNION ALL
SELECT 'Name8','男','工程部',3000,'2012-11-12'
UNION ALL
SELECT 'Name9','男','工程部',6000,'2011-11-12'
UNION ALL
SELECT 'Name10','男','工程部',3000,'2011-11-12'
UNION ALL
SELECT 'Name11','男','技术部',3000,'2011-11-12'
 

 

GROUP BY 分组查询, 一般和聚合函数配合使用

SELECT  [DEPARTMENT],SEX, COUNT(1)
FROM DBO.[STAFF]
GROUP BY SEX, [DEPARTMENT]  

该段SQL是用于查询   某个部门下的男女员工数量 其数据结果如下

开销比较大

 

GROUPING SETS

使用 GROUPING SETS 的 GROUP BY 子句可以生成一个等效于由多个简单 GROUP BY 子句的 UNION ALL 生成的结果集,并且其效率比 GROUP BY 要高,SQL Server 2008引入。

1.使用GROUP BY 子句的 UNION ALL 来统计 Staff 表中的性别、部门、薪资、入职年份

SET STATISTICS IO ON
SET STATISTICS TIME ON

SELECT N'总人数' ,'',COUNT(0) FROM [DBO].[STAFF]
UNION ALL
SELECT N'按性别划分', SEX,COUNT(0) FROM  [DBO].[STAFF] GROUP BY SEX
UNION ALL
SELECT N'按部门统计',[DEPARTMENT],COUNT(0) FROM  [DBO].[STAFF] GROUP BY [DEPARTMENT]
UNION ALL
SELECT N'按薪资统计',CONVERT(VARCHAR(10),[MONEY]),COUNT(0) FROM  [DBO].[STAFF] GROUP BY  [MONEY]
UNION ALL
SELECT N'按入职年份',CONVERT(VARCHAR(10),YEAR([CREATEDATE])),COUNT(0) FROM  [DBO].[STAFF] GROUP BY YEAR([CREATEDATE])
 


2.换成GROUPING SETS的写法

SET STATISTICS IO ON
SET STATISTICS TIME ON
GO
SELECT (CASE
WHEN GROUPING_ID(SEX,[DEPARTMENT],[MONEY],YEAR([CREATEDATE]))=15 THEN N'总人数'
WHEN GROUPING_ID(SEX,[DEPARTMENT],[MONEY],YEAR([CREATEDATE]))=7 THEN N'按性别划分'
WHEN GROUPING_ID(SEX,[DEPARTMENT],[MONEY],YEAR([CREATEDATE]))=11 THEN N'按部门统计'
WHEN GROUPING_ID(SEX,[DEPARTMENT],[MONEY],YEAR([CREATEDATE]))=13 THEN N'按薪资统计'
WHEN GROUPING_ID(SEX,[DEPARTMENT],[MONEY],YEAR([CREATEDATE]))=14 THEN N'按入职年份'
END
),
(CASE
WHEN GROUPING_ID(SEX,[DEPARTMENT],[MONEY],YEAR([CREATEDATE]))=15 THEN ''
WHEN GROUPING_ID(SEX,[DEPARTMENT],[MONEY],YEAR([CREATEDATE]))=7 THEN SEX
WHEN GROUPING_ID(SEX,[DEPARTMENT],[MONEY],YEAR([CREATEDATE]))=11 THEN [DEPARTMENT]
WHEN GROUPING_ID(SEX,[DEPARTMENT],[MONEY],YEAR([CREATEDATE]))=13 THEN CONVERT(VARCHAR(10),[MONEY])
WHEN GROUPING_ID(SEX,[DEPARTMENT],[MONEY],YEAR([CREATEDATE]))=14 THEN CONVERT(VARCHAR(10),YEAR([CREATEDATE]))
END
)
,
COUNT(1)
FROM DBO.[STAFF]
GROUP BY GROUPING SETS (SEX,[DEPARTMENT],[MONEY],YEAR([CREATEDATE]),())
 

从上述结果中可以看出,采用UNION ALL 是多次扫描表,并将扫描后的查询结果进行组合操作,会增加IO开销,减少CPU和内存开销。

采用GROUPING SETS 是一次性读取所有数据,并在内存中进行聚合操作生成结果,减少IO开销,对CPU和内存消耗增加。但GROUPING SETS 在多列分组时,其性能会比group by高。

这里扫描四次是因为我 GROUP BY GROUPING SETS (SEX,[DEPARTMENT],[MONEY],YEAR([CREATEDATE]),()) 了四列

 

ROLLUP与CUBE 

ROLLUP与CUBE  按一定的规则产生多种分组,然后按各种分组统计数据

ROLLUP与CUBE 区别:

  CUBE 会对所有的分组字段进行统计,然后合计。

  ROLLUP 按照分组顺序,对第一个字段进行组内统计,最后给出合计。

 

下面看我查询 

SELECT
      CASE WHEN (GROUPING(SEX) = 1) THEN '统计-ROLLUP'
            ELSE ISNULL(SEX, 'UNKNOWN')
       END AS SEX ,
        COUNT(0)
FROM DBO.[STAFF]
GROUP BY   SEX   WITH ROLLUP

SELECT
      CASE WHEN (GROUPING(SEX) = 1) THEN '统计-CUBE'
            ELSE ISNULL(SEX, 'UNKNOWN')
       END AS SEX ,
        COUNT(0)
FROM DBO.[STAFF]
GROUP BY   SEX   WITH CUBE

看不出差别,我们再加一列

SELECT
      CASE WHEN (GROUPING(SEX) = 1) THEN '统计-ROLLUP'
            ELSE ISNULL(SEX, 'UNKNOWN')
       END AS SEX ,
      CASE WHEN (GROUPING([DEPARTMENT]) = 1) THEN '统计-ROLLUP'
            ELSE ISNULL([DEPARTMENT], 'UNKNOWN')
       END AS [DEPARTMENT],
        COUNT(0)
FROM DBO.[STAFF]
GROUP BY   SEX,[DEPARTMENT]   WITH ROLLUP

SELECT
      CASE WHEN (GROUPING(SEX) = 1) THEN '统计-CUBE'
            ELSE ISNULL(SEX, 'UNKNOWN')
       END AS SEX ,
      CASE WHEN (GROUPING([DEPARTMENT]) = 1) THEN  '统计-CUBE'
            ELSE ISNULL([DEPARTMENT], 'UNKNOWN')
       END AS [DEPARTMENT],
        COUNT(0)
FROM DBO.[STAFF]
GROUP BY   SEX,[DEPARTMENT]  WITH CUBE

可以看出 使用 ROLLUP 会先统计分组下的,然后在对GROUP BY的第一列字段进行统计,最后计算总数,而 CUBE 则是先分组统计,然后统计GRUOP BY 的每个字段,最后进行汇总。

 

 http://www.cnblogs.com/woxpp/p/4688715.html 

时间: 2024-10-02 03:04:08

SQL Server 之 GROUP BY、GROUPING SETS、ROLLUP、CUBE的相关文章

详解T-SQL的GROUP BY GROUPING SETS

最近遇到一个情况,需要在内网系统中出一个统计报表.需要根据不同条件使用多个group by语句.需要将所有聚合的数据进行UNION操作来完成不同维度的统计查看. 直到发现在SQL SERVER 2008之后引入了GROUPING SETS这个对于GROUP BY的增强后,上面的需求实现起来就简单多了,下面我用AdventureWork中的表作为DEMO来解释一下GROUPING SETS. 假设我现在需要两个维度查询我的销售订单,查询T-SQL如下: 而使用SQL SERVER 2008之后新增

SQL Server里Grouping Sets的威力

原文:SQL Server里Grouping Sets的威力 在SQL Server里,你有没有想进行跨越多个列/纬度的聚集操作,不使用SSAS许可(SQL Server分析服务).我不是说在生产里使用开发版,也不是说安装盗版SQL Server. 不可能的任务?未必,因为通过SQL Server里所谓的Grouping Sets就可以.在这篇文章里我会给你概括介绍下Grouping Sets,使用它们可以实现哪类查询,什么是它们的性能优势. 使用Grouping Sets的聚合 假设你有个订单

PostgreSQL 10.0 preview 性能增强 - (多维分析)更快,更省内存hashed aggregation with grouping sets

标签 PostgreSQL , 10.0 , hashed aggregation with grouping sets 背景 grouping sets 是多维分析语法,PostgreSQL 从9.5开始支持这种语法,常被用于OLAP系统,数据透视等应用场景. <PostgreSQL 9.5 new feature - Support GROUPING SETS, CUBE and ROLLUP.> 由于多维分析的一个QUERY涉及多个GROUP,所以如果使用hash agg的话,需要多个H

SQL Server 总结复习(一)_MsSql

1. TVP, 表变量,临时表,CTE 的区别 TVP和临时表都是可以索引的,总是存在tempdb中,会增加系统数据库开销,而表变量和CTE只有在内存溢出时才会被写入tempdb中.对于数据量大,并且反复使用,反复进行查询关联的,建议使用临时表或TVP,数据量小,使用表变量或CTE比较合适 2. sql_variant 万能类型 可以存放所有数据类型,相当于C#中的object数据类型 3. datetime, datetime2, datetimeoffset datetime 时间有效期较小

SQL Server 2008 新特性 总结复习(一)_mssql2008

1. TVP, 表变量,临时表,CTE 的区别 TVP和临时表都是可以索引的,总是存在tempdb中,会增加系统数据库开销,而表变量和CTE只有在内存溢出时才会被写入tempdb中.对于数据量大,并且反复使用,反复进行查询关联的,建议使用临时表或TVP,数据量小,使用表变量或CTE比较合适 2. sql_variant 万能类型 可以存放所有数据类型,相当于C#中的object数据类型 3. datetime, datetime2, datetimeoffset datetime 时间有效期较小

配置SQL Server 2008的资源调控器实现负载均衡

原文:配置SQL Server 2008的资源调控器实现负载均衡 转自:http://www.ithov.com/server/93267.shtml 1.为什么引入"资源调控器"? 在SQL Server 2008之前,数据库引擎曾尝试为所有并发用户提供均衡的性能,这使我们几乎无法控制分配给用户或工作负载的优先级,而且随着并发登录的增加会雪上加霜."资源调控器"有助于防止性能问题,并识别正在使用的应用程序."资源调控器"可以控制分配给会话的CP

深入了解SQL Server 2008商业智能平台

对所有数据进行整合与管理 当你使用SQL Server 2008企业级的数据仓库平台时,你可以高效的操纵所有数据,并对其进行统一管理存储. ◆合并用于最优的报表和分析的数据 对你所有的数据进行操作,使用SQL Server 2008采用任何你希望的方式与关系数据和非关系数据进行交互,包括使你有效的存储.管理和分析无结构的数据--像文档和图片--的新的数据类型. ◆提高数据仓库性能 更快的将数据整合到数据仓库中,提高大型分区表的管理能力和性能,使你更有效的管理不断增长的数据和用户的空间. 为所有用

解析SQL Server 2008商业智能

SQL Server 2008 商业智能平台提供了一个用于数据集成.生成报表和分析的可扩展的最佳的商业智能平台,它使得当用户需要商业智能的时候,公司就能够将其提供给用户-- 对你的所有数据进行整合和管理 使用SQL Server 2008企业级的数据仓库平台可以高效的操纵你的所有数据,并对其进行统一管理存储. 合并用于最优的报表和分析的数据 对你所有的数据进行操作,使用SQL Server 2008采用任何你希望的方式与关系数据和非关系数据进行交互,包括使你有效的存储.管理和分析无结构的数据--

如何解决SQL Server数据库的"User, group, or role already exists

问题场景 在SQL Server数据库迁移时,在另外一台服务器上恢复数据库备份文件之后,需要重新创建之前数据库上的用户帐户.在创建登录用户时,需要在User Mapping中给该用户针对具体的数据库进行授权,由于恢复出来的数据库中存在同名的用户帐户,创建时会出现"User, group, or role already exists in the current database"的错误提示.详细错误信息如下: TITLE: Microsoft SQL Server Managemen