玩转数据库之 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的更多相关文章

  1. 玩转数据库之 Group by Grouping

    有的时候我们要从数据库里把数据组织成树结构再展现到页面上 像下面这样 今天我们用Group 和Grouping实现它,并总结一下它俩. 先看一下概念,再用代码一点一点去理解它们,最后我会给出完整的代码 ...

  2. Group By Grouping Sets

    Group by分组函数的自定义,与group by配合使用可更加灵活的对结果集进行分组,Grouping sets会对各个层级进行汇总,然后将各个层级的汇总值union all在一起,但却比单纯的g ...

  3. Oracle PL/SQL之GROUP BY GROUPING SETS

    [转自] http://blog.csdn.net/t0nsha/article/details/6538838 使用GROUP BY GROUPING SETS相当于把需要GROUP的集合用UNIO ...

  4. GROUP BY GROUPING SETS 示例

    --建表 create table TEst1 ( ID ), co_CODE ), T_NAME ), Money INTEGER, P_code ) ); --插入基础数据 insert into ...

  5. group by <grouping sets(...) ><cube(...)>

    GROUP BY      GROUPING SETS() 后面将还会写学习 with cube,  with rollup,以及将它们转换为标准的GROUP BY的子句GROUP SET(), CU ...

  6. SQL GROUP BY GROUPING SETS,ROLLUP,CUBE(需求举例)

    实现按照不同级别分组统计 关于GROUP BY 中的GROUPING SETS,ROLLUP,CUBE 从需求的角度理解会更加容易些. 需求举例: 假如一所学校只有两个系, 每个系有两个专业, 每个专 ...

  7. (4.6)sql2008中的group by grouping sets

    最近遇到一个情况,需要在内网系统中出一个统计报表.需要根据不同条件使用多个group by语句.需要将所有聚合的数据进行UNION操作来完成不同维度的统计查看. 直到发现在SQL SERVER 200 ...

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

    1.创建表 Staff CREATE TABLE [dbo].[Staff]( ,) NOT NULL, ) NULL, ) NULL, ) NULL, [Money] [int] NULL, [Cr ...

  9. [Oracle] Group By 语句的扩展 - Rollup、Cube和Grouping Sets

    常常写SQL语句的人应该知道Group by语句的主要使用方法是进行分类汇总,以下是一种它最常见的使用方法(依据部门.职位分别统计业绩): SELECT a.dname,b.job,SUM(b.sal ...

随机推荐

  1. Sql使用视图(简单的视图)适合入门-level

    创建以便从库更好的数据呼叫和一个数据库,以(例如,该209东东库转移205图书馆) 例:209图书馆有不同的库名:数据库(AIS20140417092531电影库)供应商表(t_Supplier ). ...

  2. 用python+selenium导入excel文件

    连接mysql #encoding=utf-8 import pymysql import time class ConnMysql(object): def __init__(self): self ...

  3. 在面对变化,撇开NO

    参观后转到供应商,看到自己的生产线流水线半自己的钣金生产线举措.这就是我一直想厂提高生产现场的想法,因为通常当我看到工作人员努力工作和繁忙的生产,只见废现场,线解决方式时,有点莫名的兴奋. 幸亏是一家 ...

  4. Swift 简简单单实现手机九宫格手势密码解锁

    原文:Swift 简简单单实现手机九宫格手势密码解锁 大家可以看到我之前的文章[HTML5 Canvas简简单单实现手机九宫格手势密码解锁] 本文是使用苹果语言对其进行了移植 颜色配色是拾取的支付宝的 ...

  5. Cocos2d-x Lua 阅读Csv文件,使用数据更方便

    在我的书或出售之前,我的源代码,有Csvshadow文件. 也许这是偏见.我与工作将是最长的轮廓Csv,所以,我会帮助不大喜欢它的游戏. Csv文件,非常格式easy,也就是说,一个数据线,字段之间用 ...

  6. 伺服驱动器UVW电机电源线相序错误

       我们有必要先了解此讨论的前提:编码器初始安装相位正确.伺服驱动器将全然"採信"电机编码器的初始安装相位所表征的电机电角度相位,无需在伺服电机 的UVW动力线接线连接后进行额外 ...

  7. PHP jpgraph的一点小提示(附安装方法)

    PHP中的GD库本身是一套很强大的绘图库了,绘制的图像基本可以满足日常要求,但强大规强大,还是不够方便哈,因为强大方便的基于PHP的GD库的jpgraph也就诞生啦! PHP默认是不启用GD库的,因为 ...

  8. 快速构建Windows 8风格应用4-FlipView数据控件

    原文:快速构建Windows 8风格应用4-FlipView数据控件 本篇博文主要介绍为什么使用FlipView控件.什么是FlipView控件.如何使用FlipView控件和FlipView控件最佳 ...

  9. JS中通过call方法实现继承

    原文:JS中通过call方法实现继承 讲解都写在注释里面了,有不对的地方请拍砖,谢谢! <html xmlns="http://www.w3.org/1999/xhtml"& ...

  10. Asterisk 未来之路3.0_0003

    原文:Asterisk 未来之路3.0_0003 Asterisk: The Hacker's PBX 如果电信公司忽视了asterisk,那么正在处于危险中.asterisk 良好的扩展性,能够创建 ...