`
zealotds
  • 浏览: 119744 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

【Microsoft SQL Server 2008 技术内幕:T-SQL语言基础】五、透视和分组

阅读更多
sql2008 t-sql

基本概念

Pivoting(透视变换)
是把数据从行状态旋转为列状态,处理过程中需要对数值进行聚合
Unpivoting(逆透视变换)
是把数据从列的状态旋转为行的状态。
它通常涉及查询数据的透视状态,将来自单个记录的多个列的值扩展为单个列中具有相同值得多个记录。
换句话说,把透视表中每个源行潜在地转换成多个行,每行代表原透视表的一个指定的列值。
Grouping (分组)
这个不多说了

透视部分的例子
---------------------------------------------------------------------
-- 1. create test table
---------------------------------------------------------------------
use tempdb;

if OBJECT_ID('dbo.Orders', 'u') is not null drop table dbo.Orders;
create table dbo.Orders (
  orderid int not null
  , orderdate date not null -- use datetime type in earlier Sql version
  , empid int not null
  , custid varchar(5) not null
  , qty int not null
  , constraint PK_Orders primary key(orderid)
)
insert into dbo.Orders(orderid, orderdate, empid, custid, qty)
values
  (30001, '20070802', 3, 'A', 10)
  , (10001, '20071224', 2, 'A', 12)
  , (10005, '20071224', 1, 'B', 20)
  , (40001, '20080109', 2, 'A', 40)
  , (10006, '20080118', 1, 'C', 14)
  , (20001, '20080212', 2, 'B', 12)
  , (40005, '20090212', 3, 'A', 10)
  , (20002, '20090216', 1, 'C', 20)
  , (30003, '20090418', 2, 'B', 15)
  , (30004, '20070418', 3, 'C', 22)
  , (30007, '20090907', 3, 'D', 30);  
select * from dbo.Orders;  
---------------------------------------------------------------------
-- 2. standard T-SQL pivoting
---------------------------------------------------------------------  
select empid
  , sum(case when custid = 'A' then qty end) as A
  , sum(case when custid = 'B' then qty end) as B
  , sum(case when custid = 'C' then qty end) as C
  , sum(case when custid = 'D' then qty end) as D
from dbo.Orders
group by empid;
---------------------------------------------------------------------
-- 3. pivot operator pivoting
---------------------------------------------------------------------
/* grammar
 * see FROM(Transact-SQL) 
select ...
from <source_table_or_table_expression>
  pivot(<agg_func>(<agg_element>)
    for <spreading_element>
    in (<list_of_target_columns>)
  ) as <result_talbe_alias>;
*/
select empid
	, A, B, C, D -- same with column list in IN clause below
from (
    select empid, custid, qty
    from dbo.Orders 
  ) as D
  pivot (sum(qty) for custid in (A,B,C,D)) as P;  

/* 
1. Pivot运算符不需要显示指定分组元素,即亦不需要指定Group By子句。
   Pivot会隐式地将不是聚合、扩展元素的那些元素作为分组元素。
2. 所以一般不会把PIVOT算符应用于源表,而是应用于表表达式。
   该表表达式中应该只包含聚合元素,扩展元素和分组元素
   如上例D中只包含了聚合元素qty,扩展元素custid,剩下的empid会自然被当作分组元素
3. 即使该源表中只包含这三类元素,还是应该把Pivot应用于表表达式。
   因为你不知道什么时候会添加新的列
*/
---------------------------------------------------------------------
-- 4. create test table2, a pivot table
---------------------------------------------------------------------
use tempdb;
if OBJECT_ID('dbo.EmpCustOrders', 'u') is not null drop table dbo.EmpCustOrders;

select empid, A, B, C, D
into dbo.EmpCustOrders
from (
    select empid, custid, qty
    from dbo.Orders
  ) as D
  pivot(sum(qty) for custid in (A, B, C, D)) as P;
select * from dbo.EmpCustOrders;
---------------------------------------------------------------------
-- 5. standard T-SQL unpivoting
---------------------------------------------------------------------
select *
from (  
  select empid, custid
    , case custid
        when 'A' then A
        when 'B' then B
        when 'C' then C
        when 'D' then D
      end as qty
  --select *    
  from dbo.EmpCustOrders
    cross join (
	  -- Sql ealier than 2008, need to use select + union below
      values('A'), ('B'), ('C'), ('D')	
    ) as Custs(custid)
) as D
-- remove null rows that represents no relationship in JOIN
where qty is not null;
---------------------------------------------------------------------
-- 6. unpivot operator unpivoting
---------------------------------------------------------------------
/* grammar
 * see FROM(Transact-SQL) 
select ...
from <source_table_or_table_expression>
  unpivot(<target_col_to_hold_source_col_values>
    for <target_col_to_hold_source_col_names>
    in (<list_of_source_columns>)
  ) as <result_talbe_alias>;
*/
select empid
	, custid, qty -- same as columns in IN clause below
from dbo.EmpCustOrders
  unpivot(qty for custid in (A, B, C, D)) as U;
/* 
1. Unpivot运算符需要在圆括号内指定:
   保存源表列值的目标列名(qty)
   保存源表列名的目标列名(custid)
   源表的列名列表(A, B, C, D)
2. Unpivot运算符会经历和前边第4个例子(t-sql unpivoting)中相同的三个步骤:
   生成副本
   提取元素
   删除交叉位置上的null值 (此步骤相对于t-sql方案不可选)
3. 经过透视变换后再逆透视不能得到相同的源表。
   因为透视变换中的聚合操作丢失了源表中的详细信息,而逆透视不会丢失信息 
*/


分组部分的例子
use tempdb;
---------------------------------------------------------------------
-- 1. grouping examples
---------------------------------------------------------------------
select empid, custid, SUM(qty) as sumqty
from dbo.Orders
group by empid, custid
union all
select empid, null, SUM(qty) as sumqty
from dbo.Orders
group by empid
union all
select null, custid, SUM(qty) as sumqty
from dbo.Orders
group by custid
union all
select null, null, SUM(qty) as sumqty
from dbo.Orders
---------------------------------------------------------------------
-- 2. grouping sets sub clause
---------------------------------------------------------------------
-- logically equals to example 1
-- advantages:
-- a. less table scan
-- b. less code
select empid, custid, SUM(qty) as sumqty
from dbo.Orders
group by GROUPING sets (
  (empid, custid)
  , (empid)
  , (custid)
  , ()
)
---------------------------------------------------------------------
-- 3. cube sub clause
---------------------------------------------------------------------
-- equals to example 2
-- CUBE(a,b,c) means the power set of (a, b, c):
--   all the combination sets of a, b and c
select empid, custid, SUM(qty) as sumqty
from dbo.Orders
group by cube(empid, custid) -- T-SQL standard
--group by empid, custid with cube -- Sql Server standard
---------------------------------------------------------------------
-- 4. rollup sub clause
---------------------------------------------------------------------
-- ROLLUP(a,b,c) differs from CUBE(a,b,c), it only returns such sub sets:
--   (a, b, c), (a, b), (a), ()
-- which means the level of input sets: a > b > c
select YEAR(orderdate), MONTH(orderdate), DAY(orderdate)
  , SUM(qty) as sumqty
from dbo.Orders
group by rollup(
  YEAR(orderdate), MONTH(orderdate), DAY(orderdate)
); -- T-SQL standard
--group by YEAR(orderdate), MONTH(orderdate), DAY(orderdate) 
--with rollup; -- Sql server standard
/* equals to: 
group by GROUPING sets (
  (YEAR(orderdate), MONTH(orderdate), DAY(orderdate))
  , (YEAR(orderdate), MONTH(orderdate))
  , (YEAR(orderdate))
  , ()
)
*/
---------------------------------------------------------------------
-- 5. grouping function
---------------------------------------------------------------------
-- Indicates whether a specified column expression in GROUP BY is 
--   aggregated or not.
select 
  grouping(empid) as grpemp
  , grouping(custid) as grpcust
  , empid, custid, SUM(qty) as sumqty
from dbo.Orders
group by cube(empid, custid);
/*
a. 如果像本文中的例子一样,所有的列都设定为not null,那么在结果中出现的
   null仅仅为占位符,此时可以根据这些null判断该列是否参与了分组。
b. 但是如果定义了允许为null的列就无法用上边的方法了,此时只能使用GROUPING
   函数来显式地指出各个列是否参与了分组运算:返回1表示参与,0则是没有参与
c. GROUPING函数在早期Sql版本中可以和WITH CUBE、WITH ROLLUP搭配使用
*/
---------------------------------------------------------------------
-- 5. grouping_id function
---------------------------------------------------------------------
-- Sql 2008 
-- Returns a integer bitmap representing the input columns' presence
--   in grouping operation. The left most bit corresponds to the first
--   (left most)column in the input list...
select 
  grouping_id(empid, custid) as groupingset  
  , empid, custid, SUM(qty) as sumqty
from dbo.Orders
group by cube(empid, custid);


0
0
分享到:
评论
1 楼 chcan1 2010-11-16  
,老师,能把后面几章 的感想和笔触写一下吗,

相关推荐

    Microsoft SQL Server 2008技术内幕:T-SQL查询

    《Microsoft SQL Server 2008技术内幕:T-SQL查询》全面深入地介绍了Microsoft SQL Server 2008中高级T-SQL查询、性能优化等方面的内容,以及SQL Server 2008新增加的一些特性。主要内容包括SQL的基础理论、查询优化...

    (第二卷)Microsoft SQL Server 2008技术内幕:T-SQL语言基础

     《Microsoft SQL Server 2008技术内幕:T-SQL语言基础》适合须要学习T-SQL的各级程序员和数据库专业人员,是他们快速掌握T-SQL的必备参考图书。 致谢 引言 第1章 T-SQL查询和编程基础 1.1 理论背景 1.2 ...

    Microsoft SQL Server 2008技术内幕:T-SQL查询(第二卷)

    阅读《Microsoft SQL Server 2008技术内幕:T-SQL查询》,可以充分地理解T-SQL语言和良好的编程实践,学会如何编写更加有效而强大的查询语句。 序言 I 致谢III 前言 V 第1章 逻辑查询处理 1.1 逻辑查询处理的...

    Microsoft SQL Server 2008技术内幕:T-SQL语言基础

    《Microsoft SQL Server 2008技术内幕:T-SQL语言基础》是Microsoft SQL Server 2008系列中的一本。书中全面深入地介绍了T-SQL的基本元素,以及SQL Server 2008中新增加的一些特性。主要包括SQL的基础理论、逻辑查询...

    (第一卷)Microsoft.SQL.Server.2008技术内幕:T-SQL语言基础

     《Microsoft SQL Server 2008技术内幕:T-SQL语言基础》适合须要学习T-SQL的各级程序员和数据库专业人员,是他们快速掌握T-SQL的必备参考图书。 致谢 引言 第1章 T-SQL查询和编程基础 1.1 理论背景 1.2 SQL ...

    Microsoft SQL Server 2008技术内幕:T-SQL查询

    本书全面深入地介绍了Microsoft SQL Server 2008中高级T-SQL查询、性能优化等方面的内容,以及SQL Server 2008新增加的一些特性。主要内容包括SQL的基础理论、查询优化、查询算法及复杂度,以及在使用子查询、表...

    Microsoft SQL Server 2008技术内幕:T-SQL语言基础

    主要包括SQL的基础理论、逻辑查询处理、SELECT查询、连接和子查询、表表达式、过滤和分组、透视转换、修改数据、事务和一致性的处理、可编程对象等内容。 书中并非系统地罗列T-SQL的各种语法元素,而是结合实践中的...

    Microsoft SQL SERVER 2008技术内幕 T-SQL查询 2/2

    《Microsoft SQL Server 2008技术内幕:T-SQL查询》全面深入地介绍了Microsoft SQL Server 2008中高级T-SQL查询、性能优化等方面的内容,以及SQL Server 2008新增加的一些特性。主要内容包括SQL的基础理论、查询优化...

    Microsoft SQL Server 2008技术内幕:T-SQL查询(英文版)

    本书全面深入地介绍了microsoft sql server 2008中高级t-sql查询、性能优化等方面的内容,以及sqlserver 2008新增加的一些特性。主要内容包括sql的基础理论、查询优化、查询算法及复杂度,以及在使用子查询、表...

    Microsoft+SQL+Server+2008技术内幕:T-SQL查询_源代码及附录 中文版

    阅读《Microsoft SQL Server 2008技术内幕:T-SQL查询》,可以充分地理解T-SQL语言和良好的编程实践,学会如何编写更加有效而强大的查询语句。 目录 ------------------------------------------------------------...

    Microsoft+SQL+Server+2008技术内幕:T-SQL查询_源代码及附录A

    T-SQL查询_源代码,逻辑查询处理,集合论,查询优化,子查询排名,数据聚合和透视,数据修改

    MicrosoftSQLServer2008技术内幕:T-SQL查询

    资源名称:Microsoft SQL Server 2008技术内幕:T-SQL查询内容简介:本书全面深入地介绍了Microsoft SQL Server 2008中高级T-SQL查询、性能优化等方面的内容,以及SQLServer 2008新增加的一些特性。主要内容包括SQL...

    Microsoft SQL Server 2005技术内幕:T-SQL查询

    第1章 T-SQL查询和编程基础  1.1 理论背景  1.2 SQL SERVER体系结构  1.3 创建表和定义数据完整性  1.4 总结 第2章 单表查询  2.1 SELECT语句的元素  2.2 谓词和运算符  2.3 CASE表达式  2.4 NULL...

    SQLServer2008技术内幕T-SQL查询包含源代码及附录A

    《Microsoft SQL Server 2008技术内幕:T-SQL查询》全面深入地介绍了Microsoft SQL Server 2008中高级T-SQL查询、性能优化等方面的内容,以及SQL Server 2008新增加的一些特性。主要内容包括SQL的基础理论、查询优化...

    Microsoft.SQL.Server.2008技术内幕:T-SQL语言基础.part1

    【概述】: 本书是Microsoft SQL Server 2008系列中的一本。...主要包括SQL的基础理论、逻辑查询处理、SELECT查询、连接和子查询、表表达式、过滤和分组、透视转换、修改数据、事务和一致性的处理、可编程对象等内容。

    Microsoft.SQL.Server.2008技术内幕:T-SQL语言基础.part2

    【概述】: 本书是Microsoft SQL Server 2008系列中的一本。...主要包括SQL的基础理论、逻辑查询处理、SELECT查询、连接和子查询、表表达式、过滤和分组、透视转换、修改数据、事务和一致性的处理、可编程对象等内容。

    Inside Microsoft SQL Server 2008 - T-SQL Querying

    《Microsoft SQL Server 2008技术内幕:T-SQL查询》这本书的英文原版 本书全面深入地介绍了Microsoft SQL Server 2008 中高级T-SQL 查询、性能优化等方面的内容,以及SQLServer 2008 新增加的一些特性。主要内容包括...

    Microsoft SQL SERVER 2008技术内幕 T-SQL查询

    本书全面深入地介绍了Microsoft SQL Server 2008 中高级T-SQL 查询、性能优化等方面的内容,以及SQLServer 2008 新增加的一些特性。主要内容包括SQL 的基础理论、查询优化、查询算法及复杂度,以及在使用子查询、表...

    microsoft sql server 2008技术内幕 t-sql语言基础

    主要包括SQL的基础理论、逻辑查询处理、SELECT查询、连接和子查询、表表达式、过滤和分组、透视转换、修改数据、事务和一致性的处理、可编程对象等内容。 书中并非系统地罗列T-SQL的各种语法元素,而是结合实践中的...

Global site tag (gtag.js) - Google Analytics