有的時候咱們要從數據庫裏把數據組織成樹結構再展示到頁面上sql
像下面這樣數據庫
今天咱們用Group 和Grouping實現它,並總結一下它倆。ide
先看一下概念,再用代碼一點一點去理解它們,最後我會給出完整的代碼函數
Group By : 語句用於結合合計函數,根據一個或多個列對結果集進行分組。ui
Grouping :指示是否聚合 GROUP BY 列表中的指定列表達式。 在結果集中,若是 GROUPING 返回 1 則指示聚合;spa
返回 0 則指示不聚合。 若是指定了 GROUP BY,則 GROUPING 只能用在 SELECT <select> 列表、HAVING 和 ORDER BY 子句中。3d
ROLLUP :生成簡單的 GROUP BY 聚合行以及小計行或超聚合行,還生成一個總計行。code
讓咱們先建一個數據庫,並添加一些數據blog
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
看一下它們的數據ci
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