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 ...
随机推荐
- Moq 和RhinoMocks
Moq & RhinoMocks 使用Mock对象进行测试一般都会有以下三个关键步骤: 使用接口来描述需要测试的对象 为实际的产品代码实现这个接口 以测试为目的,在Mock对象中实现这个接口 ...
- poj 1679 The Unique MST 【次小生成树】【模板】
题目:poj 1679 The Unique MST 题意:给你一颗树,让你求最小生成树和次小生成树值是否相等. 分析:这个题目关键在于求解次小生成树. 方法是,依次枚举不在最小生成树上的边,然后加入 ...
- Bootstrap-maxlength使用
这是一个很酷jQuery实现Bootstrap小工具,输入用户同意的字符数.它可以让你显示字符用户插入的最大长度. 1.引入jquery.js及bootstrap-maxlength.js 2.给页面 ...
- Largest Rectangular Area in a Histogram
题目地址:https://oj.leetcode.com/problems/largest-rectangle-in-histogram/ ,刚開始事实上没做这个题,而是在做https://oj.le ...
- C#创建和初始化类
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace C_编辑 ...
- Factorization Machines 学习笔记(二)模型方程
近期学习了一种叫做 Factorization Machines(简称 FM)的算法,它可对随意的实值向量进行预測.其主要长处包含: 1) 可用于高度稀疏数据场景:2) 具有线性的计算复杂度.本文 ...
- 通俗易懂地解决中文乱码问题(2) --- 分析解决Mysql插入移动端表情符报错 ‘incorrect string value: '\xF0...
原文:[原创]通俗易懂地解决中文乱码问题(2) --- 分析解决Mysql插入移动端表情符报错 'incorrect string value: '\xF0... 这篇blog重点在解决问题,如果你对 ...
- 四大OLAP工具选型浅析
OLAP(在线分析处理)这个名词是在1993年由E.F.Codd提出来的,只是,眼下市场上的主流产品差点儿都是在1993年之前就已出来,有的甚至已有三十多年的历史了.OLAP产品不少,本文将主要涉及C ...
- C#在outlook里创建一封邮件到草稿箱
原文:C#在outlook里创建一封邮件到草稿箱 1.引用Microsoft.Office.Interop.Outlook.dll 2. 实现代码 public static int SendToD ...
- Spring IOC 之ApplicationContext的其他功能
正如上面章节所介绍的那样, org.springframework.beans.factory 包提供了管理和操作beans的 基本功能. org.springframework.context包增加 ...