Sql Server2005 Transact-SQL 新兵器学习总结之-PIVOT和UNPIVOT运算符

1.简介
PIVOT通过将表达式某一列中的唯一值转换为输出中的多个列来旋转表值表达式,并在必要时对最终输出中所需的任何其余列值执行聚合。
UNPIVOT与PIVOT执行相反的操作,将表值表达式的列转换为列值。
通俗简单的说:PIVOT就是行转列,UNPIVOT就是列传行

2.例题



-- 建立销售表
CREATE   TABLE  Sell
    (
      
[ Year ]   INT ,
      
[ Quarter ]   NVARCHAR ( 10 ),
      Quantity 
INT
    )

-- 插入测试数据
INSERT    INTO  Sell
VALUES   (  2006 ' Q1 ' 20  )
INSERT    INTO  Sell
VALUES   (  2006 ' Q2 ' 15  )
INSERT    INTO  Sell
VALUES   (  2006 ' Q2 ' 4  )
INSERT    INTO  Sell
VALUES   (  2006 ' Q3 ' 12  )
INSERT    INTO  Sell
VALUES   (  2006 ' Q4 ' 18  )

INSERT    INTO  Sell
VALUES   (  2007 ' Q1 ' 10  )
INSERT    INTO  Sell
VALUES   (  2007 ' Q2 ' 10  )

INSERT    INTO  Sell
VALUES   (  2008 ' Q1 ' 8  )
INSERT    INTO  Sell
VALUES   (  2008 ' Q2 ' 7  )
INSERT    INTO  Sell
VALUES   (  2008 ' Q3 ' 5  )
INSERT    INTO  Sell
VALUES   (  2008 ' Q3 ' 10  )
INSERT    INTO  Sell
VALUES   (  2008 ' Q4 ' 9  )
GO



-- 得到每年每季度的销售总数
SELECT    *
FROM     Sell PIVOT (  SUM (Quantity)  FOR   [ Quarter ]   IN  ( Q1, Q2, Q3, Q4 ) )   AS  P
GO


--查询得如下结果
--注意:
--如果子组为空,SQL Server生成空值。如果聚合函数是COUNT,且子组为空,则返回零。
Year   Q1  Q2  Q3  Q4
2006  20   19    12  18
2007  10   10    NULL NULL
2008  8     7      15   9

其实PIVOT在sql2000中可以用SELECT...CASE语句来实现,下面是sql2000的代码:

-- sql 2000  静态版本
SELECT    [ year ] ,
        
SUM ( CASE   WHEN   [ Quarter ]   =   ' Q1 '   THEN  Quantity
            
END AS  Q1,
        
SUM ( CASE   WHEN   [ Quarter ]   =   ' Q2 '   THEN  Quantity
            
END AS  Q2,
        
SUM ( CASE   WHEN   [ Quarter ]   =   ' Q3 '   THEN  Quantity
            
END AS  Q3,
        
SUM ( CASE   WHEN   [ Quarter ]   =   ' Q4 '   THEN  Quantity
            
END AS  Q4
FROM     sell
GROUP   BY   [ year ]


-- sql 2000 动态版本
DECLARE   @sql   NVARCHAR ( 2000 )
SELECT    @sql   =   ' select [year]  '

SELECT    @sql   =   @sql   +   ' ,sum(case when [Quarter] = '''   +   [ Quarter ]
        
+   '''  then Quantity end) as  '   +   [ Quarter ]
FROM     sell
GROUP   BY   [ Quarter ]
ORDER   BY   [ Quarter ]   ASC

select    @sql   =   @sql   +   '  from sell group by [year]  '

execute  (  @sql  )

UNPIVOT将与PIVOT执行几乎完全相反的操作,将列转换为行。


-- 创建测试表
CREATE   TABLE  TestUNPIVOT
    (
      ID 
INT ,
      A1 
NVARCHAR ( 10 ),
      A2 
NVARCHAR ( 10 ),
      A3 
NVARCHAR ( 10 )
    )

-- 插入测试数据
INSERT    INTO  TestUNPIVOT
VALUES   (  1 ' q1 ' ' q2 ' ' q3 '  )
INSERT    INTO  TestUNPIVOT
VALUES   (  2 ' q1 ' ' p1 ' ' m1 '  )
INSERT    INTO  TestUNPIVOT
VALUES   (  3 ' t1 ' ' p1 ' ' m1 '  )
GO


-- UNPIVOT  
SELECT   ID,
        A,
        
[ Value ]
FROM     (  SELECT     ID,
                    A1,
                    A2,
                    A3
          
FROM       TestUNPIVOT
        ) p UNPIVOT ( 
[ Value ]   FOR  A  IN  ( A1, A2, A3 ) ) AS  u
ORDER   BY  id  ASC ,
        a 
ASC
GO

--查询得如下结果
ID  A     Value
1    A1   q1
1    A2   q2
1    A3   q3
2    A1   q1
2    A2   p1
2    A3   m1
3    A1   t1
3    A2   p1
3    A3   m1



-- UNPIVOT 的sql 2000 实现语句:
SELECT   id,
        
' a1 '   AS   [ A ] ,
        a1 
AS   [ Value ]
FROM     TestUNPIVOT
UNION   ALL
SELECT   id,
        
' a2 ' ,
        A2
FROM     TestUNPIVOT
UNION   ALL
SELECT   id,
        
' a3 ' ,
        A3
FROM     TestUNPIVOT
ORDER   BY  id  ASC , a  ASC


3.总结
个人感觉PIVOT运算符相比SELECT...CASE语句就是代码精简了一些,似乎PIVOT可读性好像不太好!
至少我看起来PIVOT语法有点怪怪,也许是还习惯吧!我个人还是喜欢用SELECT...CASE语句.
希望微软能提供PIVOT运算符的动态版本,这样动态生成列时,不用那么费事的累加字符串

4.推荐
本系列文章(新兵器学习总结)推荐





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值