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 MyGroupDBgocreate database MyGroupDBgouse MyGroupDBgocreate Table Category( Category_ID int identity(1,1), Category_Name varchar(100))gocreate Table Product( Product_ID int identity(1,1), CategoryID int , Product_Name varchar(100))goinsert into Category values('手机')insert into Category values('台式机')insert into Category values('数码相机')goinsert 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 = CategoryIDgroup 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_NameGPfrom Category left join Product on Category_ID = CategoryIDgroup 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_NameGPfrom Category left join Product on Category_ID = CategoryIDgroup by Category_ID ,Category_Name,CategoryID,Product_Name with rolluphaving GROUPING(Category_ID)=0 and GROUPING(CategoryID)=0 |

这样的结果 我们看到只有Product_Name的Grouping有为1 了
我们就是用它去实现这棵树
selectcase 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_Namefrom Category left join Product on Category_ID = CategoryIDgroup by Category_ID ,Category_Name,CategoryID,Product_Name with rolluphaving 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 MyGroupDBgocreate database MyGroupDBgouse MyGroupDBgocreate Table Category( Category_ID int identity(1,1), Category_Name varchar(100))gocreate Table Product( Product_ID int identity(1,1), CategoryID int , Product_Name varchar(100))goinsert into Category values('手机')insert into Category values('台式机')insert into Category values('数码相机')goinsert 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,'索尼')goselect * 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 = CategoryIDgroup 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_NameGPfrom Category left join Product on Category_ID = CategoryIDgroup 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_NameGPfrom Category left join Product on Category_ID = CategoryIDgroup by Category_ID ,Category_Name,CategoryID,Product_Name with rolluphaving GROUPING(Category_ID)=0 and GROUPING(CategoryID)=0 -------------------------selectcase 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_Namefrom Category left join Product on Category_ID = CategoryIDgroup by Category_ID ,Category_Name,CategoryID,Product_Name with rolluphaving 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 ...
随机推荐
- SSAS系列——【02】多维数据(维度对象)
原文:SSAS系列——[02]多维数据(维度对象) 1.维度是什么? 数学中叫参数,物理学中是独立的时空坐标的数目.0维是一点,1维是线,2维是一个长和宽(或曲线)面积,3维是2维加上高度形成体积面. ...
- 关于小改CF协同过滤至MapReducer上的一些心得
至上次重写ID3 MR版之后,手贱继续尝试CF.之前耳闻CF这两年内非常火,论内某大神也给了单机版(90%代码来自于其).所以想试试能否改到MR上.整体来说,CF本身的机制以相似性为核心,与迭代调用几 ...
- finally 对 return 值没有影响
public int gettest(ref int i, ref int k) { int j = 0; try { return i / j; } catch (Exception Ex) { k ...
- 搭建及修正Hadoop1.2.1 MapReduce Pipes C++开发环境
Hadoop目前人气超旺,返璞归真的KV理念让人们再一次换一个角度来冷静思考一些问题. 但随着近些年来写C/C++的人越来越少,网上和官方WIKI的教程直接落地的成功率却不高,多少会碰到这样那样的问题 ...
- css2与css3的区别
css2与css3的区别 CSS3引进了一些新的元素新的特性,我收集以下,自己做了一个小结: animation(基础动画)eg: div{animation: myfirst 5s linear ...
- C语言库函数大全及应用实例十
原文:C语言库函数大全及应用实例十 [编程资料]C语言库函数大全及应用实例十 函数名: qsort 功 能: 使 ...
- 我的MYSQL学习心得(十三)
原文:我的MYSQL学习心得(十三) 我的MYSQL学习心得(十三) 我的MYSQL学习心得(一) 我的MYSQL学习心得(二) 我的MYSQL学习心得(三) 我的MYSQL学习心得(四) 我的MYS ...
- 第4章2节《MonkeyRunner源码剖析》ADB协议及服务: ADB服务SERVICES.TXT翻译参考(原创)
天地会珠海分舵注:本来这一系列是准备出一本书的,详情请见早前博文“寻求合作伙伴编写<深入理解 MonkeyRunner>书籍“.但因为诸多原因,没有如愿.所以这里把草稿分享出来,所以错误在 ...
- 快速构建Windows 8风格应用14-ShareContract概述及原理
原文:快速构建Windows 8风格应用14-ShareContract概述及原理 本篇博文主要介绍Share Contract概述.Share Contract实现原理.实现Share Contra ...
- Nancy入门
Nancy入门 当我们要接到一个新的项目的时候,我们第一时间想到的是用微软的MVC框架,但是你是否想过微软的MVC是不是有点笨重?我们这个项目用MVC是不是有点大材小用?有没有可以替代MVC的东西呢? ...