玩转数据库之 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 by Grouping 有的时候我们要从数据库里把数据组织成树结构再展现到页面上 像下面这样 今天我们用Group 和Grouping实现它,并总结一下它俩. 先看一下概念, ...
- java中list集合的内容,如何使用像数据库中group by形式那样排序
java中list集合的内容,如何使用像数据库中group by形式那样排序,比如:有一个 List<JavaBean> 他中包含了一些如下的内容JavaBean:name mone ...
- Group By Grouping Sets
Group by分组函数的自定义,与group by配合使用可更加灵活的对结果集进行分组,Grouping sets会对各个层级进行汇总,然后将各个层级的汇总值union all在一起,但却比单纯的g ...
- 数据库语法group by
因为在做pgsql和mysql数据库时group by 有报错,但是在以前做mysql5.6的时候没有问题,虽然知道时违反了sql的语法问题,但是没有搞清楚什么原因,也找了不少资料,查找原因,在盆友的 ...
- 带你了解数据库中group by的用法
前言 本章主要介绍数据库中group by的用法,也是我们在使用数据库时非常基础的一个知识点.并且也会涉及Join的使用,关于Join的用法,可以看我写的上一篇文章:带你了解数据库中JOIN的用法如有 ...
- 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 ...
- (4.6)sql2008中的group by grouping sets
最近遇到一个情况,需要在内网系统中出一个统计报表.需要根据不同条件使用多个group by语句.需要将所有聚合的数据进行UNION操作来完成不同维度的统计查看. 直到发现在SQL SERVER 200 ...
随机推荐
- Effective Java 35 Prefer annotations to naming patterns
Disadvantages of naming patterns Typographical errors may result in silent failures. There is no way ...
- 【php】mysql全局ID生成方案
生产系统随着业务增长总会经历一个业务量由小变大的过程,可扩展性是考量数据库系统高可用性的一个重要指标;在单表/数据库数据量过大,更新量不断飙涨时,MySQL DBA往往会对业务系统提出sharding ...
- 窗体DataGridView控件中按回车键时,单元格向下移动,如何能改成向右移动
方法一:protected override void OnKeyUp(System.Windows.Forms.KeyEventArgs e) { base.OnKeyUp(e); if (e.Ke ...
- [转][原]openstack-kilo--issue(六)kilo版openstack的dashboard在session超时后重新登录报错解决办法
http://blog.csdn.net/wylfengyujiancheng/article/details/50523373?locationNum=1&fps=1 1.现象描述: kil ...
- 第1章 Java中常用字符串方法总结
1.1 charAt方法——提取指定字符 1.2 codePointAt方法——提取索引字符代码点 1.3 codePointBefore方法——获取索引前一个字符的代码点 1.4 codePoint ...
- SQL优化法则小记
SQL优化技巧 1.选择最有效率的表名顺序(只在基于规则的优化器中有效): oracle的解析器按照从右到左的顺序处理 from 子句中的表名,from子句中写在最后的表(基础表 driving ta ...
- php浮点型以及精度问题
浮点型(也叫浮点数 float,双精度数 double 或实数 real) 浮点数的形式表示: LNUM [0-9]+DNUM ([0-9]*[\.]{LNUM}) | ({LNUM}[\.][0-9 ...
- FDTD扩展到所有频率
- 1644 免费馅饼 题解(c++)(S.B.S.)
1644 免费馅饼(巴蜀oj上的编号) 题面: SERKOI最新推出了一种叫做“免费馅饼”的游戏. 游戏在一个舞台上进行.舞台的宽度为W格,天幕的高度为H格,游戏者占 ...
- HDU 1828 / POJ 1177 Picture --线段树求矩形周长并
题意:给n个矩形,求矩形周长并 解法:跟求矩形面积并差不多,不过线段树节点记录的为: len: 此区间线段长度 cover: 此区间是否被整个覆盖 lmark,rmark: 此区间左右端点是否被覆盖 ...