综合练习: PIVOTUNPIVOTGROUPING SETSGROUPING_ID_1

Posted cdpj

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了综合练习: PIVOTUNPIVOTGROUPING SETSGROUPING_ID_1相关的知识,希望对你有一定的参考价值。

综合练习: PIVOT、UNPIVOT、GROUPING SETS、GROUPING_ID


/*
    《Microsoft SQL Server 2008 T-SQL Fundamentals》
*/
------------------------------------------------------------------
select *
from Orders
------------------------------------------------------------------
--按照empid分组
select empid
from Orders
group by empid
------------------------------------------------------------------
--按YY分组
select datepart(yy,orderdate)
from Orders
group by datepart(yy,orderdate)
------------------------------------------------------------------

------------------------------------------------------------------
--按empid, orderid,YY分组
select empid, orderid, datepart(yy,orderdate),
           count(*)
from Orders
group by empid, orderid, datepart(yy,orderdate)
------------------------------------------------------------------
----按empid, YY分组
select empid,  datepart(yy,orderdate) as YY,
           count(*) as cnt
from Orders
group by empid,  datepart(yy,orderdate)
------------------------------------------------------------------
----按empid, YY分组
select empid,  YEAR(orderdate) as YY    --, count(*) as cnt
from Orders
------------------------------------------------------------------
        --从上面这个步骤,直接得出最后的结果,交叉时之前的子查询不要分组,统计,   还是多熟悉一下pivot,unpivot的语法
        select empid, [2007], [2008], [2009]
        from (                          
                    select empid,  datepart(yy,orderdate) as YY
                    from Orders
                ) as d
            pivot(count(YY) for YY in([2007], [2008], [2009])) as p    --对于交叉时,一直不想在这里用列举的方法,假使这里的值很多时?
------------------------------------------------------------------
            ----按empid, YY分组,不需要的思考过程,就向后缩进
            --select empid, -- datepart(yy,orderdate),
            --           (case when datepart(yy,orderdate)=‘2007‘ then count(*) end) AS cnt2007,
            --           (case when datepart(yy,orderdate)=‘2008‘ then count(*) end) AS cnt2008,
            --           (case when datepart(yy,orderdate)=‘2009‘ then count(*) end) AS cnt2009
            --from Orders
            --group by empid,  datepart(yy,orderdate)
------------------------------------------------------------------
----按empid,这就是最后的结果,虽然是最后的结果,是以订单数量的次数在相加
select empid, -- datepart(yy,orderdate),
          count(case when datepart(yy,orderdate)=2007 then qty end) AS cnt2007,
          count(case when datepart(yy,orderdate)=2008 then qty end) AS cnt2008,
          count(case when datepart(yy,orderdate)=2009 then qty end) AS cnt2009
from Orders
group by empid
------------------------------------------------------------------
----按empid,这就是最后的结果,以出现的 “年” 相同的次数在相加
select empid, -- datepart(yy,orderdate),
          count(case when year(orderdate)=2007 then year(orderdate) end) AS cnt2007,
          count(case when year(orderdate)=2008 then year(orderdate) end) AS cnt2008,
          count(case when year(orderdate)=2009 then year(orderdate) end) AS cnt2009
from Orders
group by empid
------------------------------------------------------------------
--将查询的结果集,插入到另外一个表中去,目的是什么? ---看这么查询得出这么整齐的结果,当然是想训练UNPIVOT
IF OBJECT_ID(dbo.EmpYearOrders, U) IS NOT NULL DROP TABLE dbo.EmpYearOrders;

SELECT empid, [2007] AS cnt2007, [2008] AS cnt2008, [2009] AS cnt2009
INTO dbo.EmpYearOrders
FROM (SELECT empid, YEAR(orderdate) AS orderyear
      FROM dbo.Orders) AS D
  PIVOT(COUNT(orderyear)
        FOR orderyear IN([2007], [2008], [2009])) AS P;

SELECT * FROM dbo.EmpYearOrders;
    empid       cnt2007     cnt2008     cnt2009
    ----------- ----------- ----------- -----------
     1           1           1          1
     2           1           2          1
     3           2           0          2
------------------------------------------------------------------
--将上面这个结果,转化为下面的,打散开
empid       orderyear   numorders
----------- ----------- -----------
1           2007        1
1           2008        1
1           2009        1
2           2007        1
2           2008        2
2           2009        1
3           2007        2
3           2009        2

SELECT empid, orderyear, numorders
FROM dbo.EmpYearOrders
  UNPIVOT(numorders 
                   for orderyear in(cnt2007, cnt2008,cnt2009)) AS U
where numorders <> 0
------------------------------------------------------------------

------------------------------------------------------------------
--
--select * from Orders
select grouping(empid) as groupingset, empid, custid, year(orderdate) as orderyear, sum(qty) as sumqty
from Orders
group by
    grouping sets(
                            (empid, custid, year(orderdate)),
                            (empid,  year(orderdate)),
                            (custid, year(orderdate))      --如果分组包含(),则结果集中将会计算总的数量(sumqty = 205)
                         )
------------------------------------------------------------------
-- Write a query against the Orders table that returns the total quantities for each: 
-- (employee, customer, and order year), (employee and order year), (customer and order year). 
-- Include a result column in the output that uniquely identifies the grouping set with which the current row is associated. 
-- 用GROUPING_ID函数为与每一行相关联的分组集生成唯一的标识符
select grouping_id(empid,custid,year(orderdate)) as groupingset, empid, custid, year(orderdate) as orderyear, sum(qty) as sumqty
from Orders
group by
    grouping sets(
                   (empid, custid, year(orderdate)),
                   (empid,  year(orderdate)),
                   (custid, year(orderdate))                        
                 )

 感悟:也许国内出书都是以结果为导向,或者为升职、或者为名,反正出的书、或者翻译的书籍,即使自己懂、理解、或没完全理解透彻,翻译出来的书籍都不是那么理想的,
            并不是在否定他们的劳动成果,你出书,面向哪个级别的书籍,就应该针对哪个级别要进行理解性的讲解。

以上是关于综合练习: PIVOTUNPIVOTGROUPING SETSGROUPING_ID_1的主要内容,如果未能解决你的问题,请参考以下文章

第1章 综合练习

组合数据类型练习,综合练习

练习:自己写一个容器(数组)综合练习

Packet Tracer - 综合技能练习

综合练习:词频统计

0517JS综合练习挂事件练习