设为首页 收藏本站
查看: 796|回复: 0

[经验分享] SQL Server 2005中PIVOT與UNPIVOT

[复制链接]

尚未签到

发表于 2016-11-2 01:14:59 | 显示全部楼层 |阅读模式
  /*
  PIVOT
  PIVOT和UNPIVOT关系运算符是SQL Server 2005提供的新增功能,因此,对升级到SQL Server 2005的数据库使用PIVOT和UNPIVOT时,数据库的兼容级别必须设置为90(可以使用sp_dbcmptlevel存储过程设置兼容级别)。
在查询的FROM子句中使用PIVOT和UNPIVOT,可以对一个输入表值表达式执行某种操作,以获得另一种形式的表。PIVOT运算符将输入表的行旋转为列,并能同时对行执行聚合运算。而UNPIVOT运算符则执行与PIVOT运算符相反的操作,它将输入表的列旋转为行。
*/
  -->Title:生成測試數據
-->Author:wufeng4552
-->Date :2009-09-14 09:37:37
if not object_id('Orders') is null
drop table Orders
Go
Create table Orders([ProductID] int,[OrderMonth] int,[SubTotal] decimal(18,2))
Insert Orders
select 1,5,100.00 union all
select 1,6,100.00 union all
select 2,5,200.00 union all
select 2,6,200.00 union all
select 2,7,300.00 union all
select 3,5,400.00 union all
select 3,5,400.00
Go
select [ProductID],
isnull([5],0)[5月],
isnull([6],0)[6月],
isnull([7],0)[7月]
from
Orders pivot
(sum([SubTotal])
for [OrderMonth]
in([5],[6],[7]))as pvt
/*
ProductID 5月 6月 7月
----------- --------------------------------------- --------------------------------------- ---------------------------------------
1 100.00 100.00 0.00
2 200.00 200.00 300.00
3 800.00 0.00 0.00
  (3 個資料列受到影響)
*/
/*在上面的语句中,Orders是输入表,OrderMonth是透视列(pivot_column)
  SubTotal是值列(value_column)。上面的语句将按下面的步骤获得输出结果集:
  a.PIVOT首先按值列之外的列(ProductID和OrderMonth)对输入表Orders进行分组汇总,类似执行下面的语句:
  */
  SELECT ProductID,
OrderMonth,
SUM (Orders.SubTotal) AS SumSubTotal
FROM Orders
GROUP BY ProductID,OrderMonth
/*
ProductID OrderMonth SumSubTotal
----------- ----------- ---------------------------------------
1 5 100.00
2 5 200.00
3 5 800.00
1 6 100.00
2 6 200.00
2 7 300.00
  (6 個資料列受到影響)
*/
  /*
  b.PIVOT根据FOR Orders.OrderMonth IN指定的值5、6、7,首先在结果集中建立名为5、6、7的列,
  上述所示的中间结果中取出OrderMonth列中取出相符合的值,分别放置到5、6、7的列中。
  此时得到的结果集的别名为pvt(见语句中AS pvt的指定)
  c.最后根据SELECT ProductID, [5] AS 五月, [6] AS 六月, [7] AS 七月FROM的指定,
  从别名pvt结果集中检索数据,并分别将名为5、6、7的列在最终结果集中重新命名为五月、六月、七月。
  这里需要注意的是FROM的含义,其表示从经PIVOT关系运算符得到的pvt结果集中检索数据,而不是从Orders中检索数据。
  */
  /*
  PIVOT 注意點
  table_source PIVOT <pivot_clause>
  指定对table_source表中的pivot_column列进行透视。table_source可以是一个表、表表达式或子查询。
  不允许使用COUNT(*)系统聚合函数,可以用戶自定義
  FOR pivot_column PIVOT运算符的透视列。pivot_column必须是可隐式或显式转换为nvarchar()的类型
  IN ( column_list )
  在PIVOT子句中,column_list列出pivot_column中将成为输出表的列名的值。
  */
  /*
  UNPIVOT
  UNPIVOT与PIVOT执行几乎完全相反的操作,将列转换为行。但是,UNPIVOT并不完全是PIVOT的逆操作,由于在执行PIVOT过程中,数据已经被进行了分组汇总,所以使用UNPIVOT并不会重现原始表值表达式的结果。
  上述结果集存储在一个名为MyPvt的表中,现在需要将列标识符“五月”、“六月”和“七月”转换到对应于相应产品ID的行值(即返回到最初所示的格式)。这意味着必须另外标识两个列,一个用于存储月份,一个用于存储销售额。为了便于理解,仍旧分别将这两个列命名为OrderMonth和SumSubTotal。
  */
  IF OBJECT_ID('MYPVT')IS NOT NULL DROP TABLE MYPVT
GO
CREATE TABLE MyPvt (ProductID int, [5]int, [6] int,[7]int); --建立MyPvt表
INSERT INTO MyPvt VALUES (1,100,100,0);
INSERT INTO MyPvt VALUES (2,200,200,200);
INSERT INTO MyPvt VALUES (3,800,0,0);
--执行UNPIVOT
SELECT ProductID,
OrderMonth,
SubTotal
FROM MYPVT UNPIVOT
(SUBTOTAL FOR ORDERMONTH IN([5],[6],[7]))
AS UNPVT
/*
ProductID OrderMonth SubTotal
----------- -------------------------------------------------------------------------------------------------------------------------------- -----------
1 5 100
1 6 100
1 7 0
2 5 200
2 6 200
2 7 200
3 5 800
3 6 0
3 7 0
  (9 個資料列受到影響)
  */
  /*
  上面的语句将按下面的步骤获得输出结果集:
  a.首先建立一个临时结果集的结构,该结构中包含MyPvt表中除IN (五月, 六月, 七月)之外的列,以及SubTotal FOR OrderMonth中指定的值列(SubTotal)和透视列(OrderMonth)。
  b.将在MyPvt中逐行检索数据,将表的列名称(在IN (五月, 六月, 七月)中指定)放入OrderMonth列中,将相应的值放入到SubTotal列中。最后得到的结果集如表5-6所示。
  */

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-294262-1-1.html 上篇帖子: VB.NET DMO SQL SERVER备份恢复 下篇帖子: Delphi处理SQL Server多媒体数据
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表