Group by Grouping
玩转数据库之 Group by Grouping
有的时候我们要从数据库里把数据组织成树结构再展现到页面上
像下面这样
今天我们用Group 和Grouping实现它,并总结一下它俩。
先看一下概念,再用代码一点一点去理解它们,最后我会给出完整的代码
Group By : 语句用于结合合计函数,根据一个或多个列对结果集进行分组。
Grouping :指示是否聚合 GROUP BY 列表中的指定列表达式。 在结果集中,如果 GROUPING 返回 1 则指示聚合;
返回 0 则指示不聚合。 如果指定了 GROUP BY,则 GROUPING 只能用在 SELECT <select> 列表、HAVING 和 ORDER BY 子句中。
ROLLUP :生成简单的 GROUP BY 聚合行以及小计行或超聚合行,还生成一个总计行。
让我们先建一个数据库,并添加一些数据
use master go if exists( select 1 from sysdatabases where name = 'MyGroupDB' ) ALTER DATABASE MyGroupDB SET SINGLE_USER with ROLLBACK IMMEDIATE drop database MyGroupDB go create database MyGroupDB go use MyGroupDB go create Table Category ( Category_ID int identity(1,1), Category_Name varchar (100) ) go create Table Product ( Product_ID int identity(1,1), CategoryID int , Product_Name varchar (100) ) go insert into Category values ( '手机' ) insert into Category values ( '台式机' ) insert into Category values ( '数码相机' ) go insert into Product values (1, '诺基亚' ) insert into Product values (1, '三星' ) insert into Product values (1, '苹果' ) insert into Product values (2, 'HP' ) insert into Product values (2, 'IBM' ) insert into Product values (2, 'Dell' ) insert into Product values (3, '佳能' ) insert into Product values (3, '尼康' ) insert into Product values (3, '索尼' ) go |
看一下它们的数据
select * from Category left join Product on Category_ID = CategoryID |
我们把它们用Group By分一下组

select Category_ID ,
Category_Name,
CategoryID,
Product_Name
from Category
left join Product on Category_ID = CategoryID
group by Category_ID ,CategoryID,Category_Name,Product_Name

我们看到这样和没有分组时展现的数据是一样的,让我们加上 ROLLUP 加上合计行
select Category_ID , Category_Name, CategoryID, Product_Name from Category left join Product on Category_ID = CategoryID group by Category_ID ,CategoryID,Category_Name,Product_Name with rollup |
我们看到了好多NULL数据,而且很有规律
这些规律我们可以用Grouping 看到
select Category_ID , GROUPING (Category_ID) as Category_IDGP, Category_Name, GROUPING (Category_Name) as Category_NameGP, CategoryID, GROUPING (CategoryID) as CategoryIDGP, Product_Name, GROUPING (Product_Name) as Product_NameGP from Category left join Product on Category_ID = CategoryID group by Category_ID ,Category_Name,CategoryID,Product_Name with rollup |
你会发现那些Null值就是Grouping 为1的时候
最后一行的合计是Categrory_ID的,我们不需要,CategoryID的合计我们也不需要我们要怎么去掉它们呢,在having 里
select Category_ID , GROUPING (Category_ID) as Category_IDGP, CategoryID, GROUPING (CategoryID) as CategoryIDGP, Category_Name, GROUPING (Category_Name) as Category_NameGP, Product_Name, GROUPING (Product_Name) as Product_NameGP from Category left join Product on Category_ID = CategoryID group by Category_ID ,Category_Name,CategoryID,Product_Name with rollup having GROUPING (Category_ID)=0 and GROUPING (CategoryID)=0 |
这样的结果 我们看到只有Product_Name的Grouping有为1 了
我们就是用它去实现这棵树
select case GROUPING (Product_Name) when 1 then Category_Name else '' end as Category_Name, case GROUPING (Product_Name) when 0 then Product_Name else '' end as Product_Name from Category left join Product on Category_ID = CategoryID group by Category_ID ,Category_Name,CategoryID,Product_Name with rollup having GROUPING (Category_ID)=0 and GROUPING (CategoryID)=0 order by Category_ID ,Product_Name |
下面是完整的代码
use master go if exists( select 1 from sysdatabases where name = 'MyGroupDB' ) ALTER DATABASE MyGroupDB SET SINGLE_USER with ROLLBACK IMMEDIATE drop database MyGroupDB go create database MyGroupDB go use MyGroupDB go create Table Category ( Category_ID int identity(1,1), Category_Name varchar (100) ) go create Table Product ( Product_ID int identity(1,1), CategoryID int , Product_Name varchar (100) ) go insert into Category values ( '手机' ) insert into Category values ( '台式机' ) insert into Category values ( '数码相机' ) go insert into Product values (1, '诺基亚' ) insert into Product values (1, '三星' ) insert into Product values (1, '苹果' ) insert into Product values (2, 'HP' ) insert into Product values (2, 'IBM' ) insert into Product values (2, 'Dell' ) insert into Product values (3, '佳能' ) insert into Product values (3, '尼康' ) insert into Product values (3, '索尼' ) go select * from Category left join Product on Category_ID = CategoryID -------------------------------------------------------- select Category_ID , Category_Name, CategoryID, Product_Name from Category left join Product on Category_ID = CategoryID group by Category_ID ,CategoryID,Category_Name,Product_Name with rollup -------------------------------------------------------- select Category_ID , GROUPING (Category_ID) as Category_IDGP, Category_Name, GROUPING (Category_Name) as Category_NameGP, CategoryID, GROUPING (CategoryID) as CategoryIDGP, Product_Name, GROUPING (Product_Name) as Product_NameGP from Category left join Product on Category_ID = CategoryID group by Category_ID ,Category_Name,CategoryID,Product_Name with rollup ---------------------- select Category_ID , GROUPING (Category_ID) as Category_IDGP, CategoryID, GROUPING (CategoryID) as CategoryIDGP, Category_Name, GROUPING (Category_Name) as Category_NameGP, Product_Name, GROUPING (Product_Name) as Product_NameGP from Category left join Product on Category_ID = CategoryID group by Category_ID ,Category_Name,CategoryID,Product_Name with rollup having GROUPING (Category_ID)=0 and GROUPING (CategoryID)=0 ------------------------- select case GROUPING (Product_Name) when 1 then Category_Name else '' end as Category_Name, case GROUPING (Product_Name) when 0 then Product_Name else '' end as Product_Name from Category left join Product on Category_ID = CategoryID group by Category_ID ,Category_Name,CategoryID,Product_Name with rollup having GROUPING (Category_ID)=0 and GROUPING (CategoryID)=0 order by Category_ID ,Product_Name |
Group by Grouping的更多相关文章
- 玩转数据库之 Group by Grouping
有的时候我们要从数据库里把数据组织成树结构再展现到页面上 像下面这样 今天我们用Group 和Grouping实现它,并总结一下它俩. 先看一下概念,再用代码一点一点去理解它们,最后我会给出完整的代码 ...
- Group By Grouping Sets
Group by分组函数的自定义,与group by配合使用可更加灵活的对结果集进行分组,Grouping sets会对各个层级进行汇总,然后将各个层级的汇总值union all在一起,但却比单纯的g ...
- Oracle PL/SQL之GROUP BY GROUPING SETS
[转自] http://blog.csdn.net/t0nsha/article/details/6538838 使用GROUP BY GROUPING SETS相当于把需要GROUP的集合用UNIO ...
- GROUP BY GROUPING SETS 示例
--建表 create table TEst1 ( ID ), co_CODE ), T_NAME ), Money INTEGER, P_code ) ); --插入基础数据 insert into ...
- group by <grouping sets(...) ><cube(...)>
GROUP BY GROUPING SETS() 后面将还会写学习 with cube, with rollup,以及将它们转换为标准的GROUP BY的子句GROUP SET(), CU ...
- SQL GROUP BY GROUPING SETS,ROLLUP,CUBE(需求举例)
实现按照不同级别分组统计 关于GROUP BY 中的GROUPING SETS,ROLLUP,CUBE 从需求的角度理解会更加容易些. 需求举例: 假如一所学校只有两个系, 每个系有两个专业, 每个专 ...
- (4.6)sql2008中的group by grouping sets
最近遇到一个情况,需要在内网系统中出一个统计报表.需要根据不同条件使用多个group by语句.需要将所有聚合的数据进行UNION操作来完成不同维度的统计查看. 直到发现在SQL SERVER 200 ...
- SQL Server 之 GROUP BY、GROUPING SETS、ROLLUP、CUBE
1.创建表 Staff CREATE TABLE [dbo].[Staff]( ,) NOT NULL, ) NULL, ) NULL, ) NULL, [Money] [int] NULL, [Cr ...
- [Oracle] Group By 语句的扩展 - Rollup、Cube和Grouping Sets
常常写SQL语句的人应该知道Group by语句的主要使用方法是进行分类汇总,以下是一种它最常见的使用方法(依据部门.职位分别统计业绩): SELECT a.dname,b.job,SUM(b.sal ...
随机推荐
- Hadoop上传文件的报错
baidu了很多,都说防火墙,datanode没有正常启动的问题,可是检查了都是正常,后来还是在老外的网站上找到了解决的方法 修改了/etc/security/limits.conf文件,上传成功 这 ...
- CSharp设计模式读书笔记(8):桥接模式(学习难度:★★★☆☆,使用频率:★★★☆☆)
桥接模式(Bridge Pattern): 将抽象部分与它的实现部分分离,使它们都可以独立地变化.它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模 ...
- C和指针 (pointers on C)——第一章:高速启动
大多数人并不认为有几类人猿学校计划非常赞同C学习好,然后看多本书. 仅仅作为读书笔记写.有时还包括一些题目和答案. 这样的公开栏,这两种玉引砖敲,对于自勉,鼓励王! 第一章:手 我每次都是复习的来写. ...
- c# WebBrowser开发参考资料
原文:c# WebBrowser开发参考资料 c# WebBrowser开发参考资料,所有资料的采集均来自网上 话说有了WebBrowser类,终于不用自己手动封装SHDocVw的AxWebBrows ...
- c# 文件同步服务器,iis 集群 ,代码同步(二)
打算自己做一个 集群 代码同步软件. 基于Socket 和 FileSystemWatcher .
- 【ThinkingInC++】66、pointer Stash的使用
头文件PStash.h /** * 书本:[ThinkingInC++] * 功能:pointer Stash的头文件 * 时间:2014年10月5日14:33:15 * 作者:cutter_poin ...
- Humming Bird A20 SPI2驱动编译
Humming Bird A20 SPI2使用编译 Yao.GUET 2014-07-17,请注明出处:http://blog.csdn.net/Yao_GUET A20上带有4个spi接口,因为Hu ...
- android如何判断服务是否正在运行状态
如何检查后台服务(Android的Service类)是否正在运行?我希望我的Activity能够显示Service的状态,然后我可以打开或者关闭它. /** * 判断服务是否处于运行状态. * @pa ...
- ActiveReports 9实战教程(2): 准备数据源(设计时、运行时)
原文:ActiveReports 9实战教程(2): 准备数据源(设计时.运行时) 在上讲中<ActiveReports 9实战教程(1): 手把手搭建环境Visual Studio 2013 ...
- Sql Server 存储过程中查询数据无法使用 Union(All)
原文:Sql Server 存储过程中查询数据无法使用 Union(All) 微软Sql Server数据库中,书写存储过程时,关于查询数据,无法使用Union(All)关联多个查询. 1.先看一段正 ...