一般我们在使用SQL语句实现行列转置时候,最常用的方法无外乎就是 case语句来实现,但是如果需要需要转置的列太多,那么case起来语句就无限庞大,十分不方便,sql server中的PIVOT就可以帮助我们解决此类问题

PIVOT語法,如下:

SELECT <non-pivoted column>,
    [first pivoted column] AS <column name>,
    [second pivoted column] AS <column name>,
    ...
    [last pivoted column] AS <column name>
FROM
    (<SELECT query that produces the data>)
   AS <alias for the source query>
PIVOT
(
    <aggregation function>(<column being aggregated>)
FOR
[<column that contains the values that will become column headers>]
    IN ( [first pivoted column], [second pivoted column],
    ... [last pivoted column])
) AS <alias for the pivot table>
<optional ORDER BY clause>;

PIVOT語法剖析:

PIVOT的語法分三層,用三個步驟來使用。
第一步驟:先把要PIVOT的原始資料查詢(Query)好。
第二步驟:設定好PIVOT的欄位與方式。
第三步驟:依PIVOT好了的資料,呈現結果。

SELECT <non-pivoted column>,    ---- 第三步驟在此,呈現PIVOT後的資料。
    [first pivoted column] AS <column name>,
    [second pivoted column] AS <column name>,
    ...
    [last pivoted column] AS <column name>
FROM
   (<SELECT query that produces the data>) ---- 第一步驟在此,準備資料(Query)。
   AS <alias for the source query>
PIVOT ---- 第二步驟在此,依第一步驟的資料欄位來設定PIVOT方式。
(
    <aggregation function>(<column being aggregated>)
FOR
[<column that contains the values that will become column headers>]
    IN ( [first pivoted column], [second pivoted column],
    ... [last pivoted column])
) AS <alias for the pivot table>
<optional ORDER BY clause>;


用實戰案例說明:

實戰案例一:

--## 一維PIVOT 

目的:統計各狀態(ldap_sts)的數量。
select *  ---- 第三步:把PIVOT好的資料直接呈現出來。
from
(
    select [ldap_id], [ldap_sts] from ccldap   -- 第一步:準備資料。
          -- 只從原資料檔選了兩個欄位,PK欄位(ldap_id)與狀態欄位(ldap_sts)。
) S  -- 一定要有,不然會語法錯誤。
pivot
(
    count([ldap_id]) -- 統計計數數量
    for [ldap_sts] in ([1],[2],[3],[4],[5],[6],[7])  -- 為欄位[ldap_sts]的狀態值[1][2]…[7]進行統計計算。
-- 注意:[1][2]…[7]是[ldap_sts]的值,以欄位表示法來描述[ldap_sts]的值。
) P  -- 一定要有,不然會語法錯誤。

下面是執行結果:

1         2         3         4         5         6         7   <---狀態值
--------- --------- --------- --------- --------- --------- ---------
1         12528     68519     120       8         5         36  <---狀態數量

(1 個資料列受到影響)

======================================================
# 實戰案例二:

--## 二維PIVOT
目的:統計不同用途(app_rsn_cod )下,各狀態(ldap_sts)的數量。
select *  -- 第三步:把PIVOT好的資料直接呈現出來。
from
(
    select [ldap_id], [ldap_sts], [app_rsn_cod] from ccldap   -- 第一步:準備資料。
         -- 從原資料檔選了三個欄位,PK欄位(ldap_id)、狀態欄位(ldap_sts)與用途欄位(app_rsn_cod)。
) S  -- 一定要有,不然會語法錯誤。
pivot
(
    count([ldap_id])-- 統計計數數量
    for [ldap_sts] in ( [1],[2],[3],[4],[5],[6],[7])  -- 為欄位[ldap_sts]的狀態值[1][2]…[7]進行統計計算。
-- 注意:[1][2]…[7]是[ldap_sts]的值,以欄位表示法來描述[ldap_sts]的值。
) P

下面是執行結果:

(用途)      (狀態1)   (狀態2)   (狀態3)   (狀態4)   (狀態5)   (狀態6)   (狀態7)  
app_rsn_cod 1         2         3         4         5         6         7
----------- --------- --------- --------- --------- --------- --------- ---------
NULL        0         12515     59676     0         2         0         0
1           1         10        8104      1         4         5         0
2           0         3         739       119       2         0         36

(3 個資料列受到影響)

注意到了嗎,在此例的第二步驟,並未設定用途欄位(app_rsn_cod),但在最後的PIVOT結果資料卻神奇的合併(join)成希望達到的效果。

## 補充一個應用 on  2013/1/7:

-- 財產折舊傳票 Query Command.
DECLARE @ac_yr NCHAR(4);
SET @ac_yr = '2012';
SELECT [ac_yr_tw]=Cast(ac_yr - 1911 AS VARCHAR(3))
  ,[tckt_ym]=adg.cvtY4mToY3m(tckt_ym)
  ,[財產預算內],[財產預算外],[實小財產預算內],[軟體預算內],[軟體預算外],[大修預算內],[大修預算外] 
FROM ( 
  SELECT ac_yr -- key
  ,tckt_ym       -- key
  ,tckt_num     -- measure
  ,[pivot_col]=Case
     When bdg_tpe = 'A' and dpr_grp = 'A' Then '財產預算內' -- pivot column 
     When bdg_tpe = 'B' and dpr_grp = 'A' Then '財產預算外'
     When bdg_tpe = 'A' and dpr_grp = 'B' Then '軟體預算內'
     When bdg_tpe = 'B' and dpr_grp = 'B' Then '軟體預算外'
     When bdg_tpe = 'A' and dpr_grp = 'D' Then '大修預算內'
     When bdg_tpe = 'B' and dpr_grp = 'D' Then '大修預算外'
 End
 FROM gcastdprtckt
 WHERE ac_yr = @ac_yr 
) S
PIVOT
(
    MAX(tckt_num) -- 其實只會有一筆,但不用aggregation function 不會出現。
    FOR [pivot_col] in ([財產預算內],[財產預算外],[實小財產預算內],[軟體預算內],[軟體預算外],[大修預算內],[大修預算外])
) P

# 結果象這樣

原文转载:http://rely1020.blog.ithome.com.tw/post/1606/39111

使用SQL SERVER PIVOT实现行列转置的更多相关文章

  1. sql server pivot/unpivot 行列互转

    有时候会碰到行转列的需求(也就是将列的值作为列名称),通常我都是用 CASE END + 聚合函数来实现的. 如下: declare @t table (StudentName nvarchar(20 ...

  2. 行转列:SQL SERVER PIVOT与用法解释

    在数据库操作中,有些时候我们遇到需要实现“行转列”的需求,例如一下的表为某店铺的一周收入情况表: WEEK_INCOME(WEEK VARCHAR(10),INCOME DECIMAL) 我们先插入一 ...

  3. SQL SERVER 中的行列转换小结

    1. 介绍说明 前段时间组内的小伙伴在升级维护项目中,经常涉及一些复杂的数据转换问题,让我去看下有些地方怎么处理,我发现好多都是涉及到行列转换的问题,处理起来经常会比较麻烦,借此也总结一下,方便以后的 ...

  4. SQL Server pivot 行转列遇到的问题

    前段时间开发系统时,有个功能是动态加载列,于是就使用了SQL Server自带的PIVOT函数进行行转列,开始用的非常溜,效果非常好.但是提交测试后问题来了,测试添加的列名中包含空格,然后就杯具了,功 ...

  5. SQL SERVER PIVOT与用法解释

    通俗简单的说:PIVOT就是行转列,UNPIVOT就是列传行 在数据库操作中,有些时候我们遇到需要实现“行转列”的需求,例如一下的表为某店铺的一周收入情况表: WEEK_INCOME(WEEK ),I ...

  6. SQL SERVER PIVOT使用

    参照这个网址介绍 http://www.cnblogs.com/lwhkdash/archive/2012/06/26/2562979.html 一般SQL Server的函数都会识别为紫色,可是PI ...

  7. [转]Oracle SQL函数pivot、unpivot转置函数实现行转列、列转行

    原文地址:http://blog.csdn.net/seandba/article/details/72730657 函数PIVOT.UNPIVOT转置函数实现行转列.列转行,效果如下图所示: 1.P ...

  8. MSSQL PIVOT 实现行列转置

    create table #temp ( ProdStep varchar(40), ModuleStatus varchar(40), Cnt int ); insert into #temp va ...

  9. SQL SERVER pivot(行转列),unpivot(列转行)

    [pivot]行转列:多行变一列 假设学生成绩表Score1 Name Subject Score 小张 语文 88 小花 数学 89 小张 数学 90 Name 语文 数学 小花 null 89 小 ...

随机推荐

  1. Linux平台下停止后台进程脚本编写

    1.场景说明 [root@master ~]# jps -m 33050 Jps -m 3299 NameNode 3747 ResourceManager 9028 ConsoleConsumer  ...

  2. Spring Cloud(Dalston.SR5)--Feign 与 Hystrix 断路器整合

    创建项目 要使 Feign 与 Hystrix 进行整合,我们需要增加 Feign 和 Hystrix 的依赖,修改 POM.xml 中增加以下依赖项如下: <?xmlversion=" ...

  3. Excel技巧--批量生成指定名称的文件夹

    当我要按excel表当中的名字来批量生成文件夹时,手动一个个制作很麻烦(特别是成百上千个时).于是我们可以这么做: 1.在名字右侧建立公式:"MD "&A2. 2.将公式拖 ...

  4. 让VCL的皮肤用在手机程序里 让安桌程序不山寨[转]

    ① 就用那个bitmap设计工具,先打开vcl里的皮肤(..... \Embarcadero\RAD Studio\12.0\Redist\styles\vcl里) ② save as      转换 ...

  5. 在windows server上配置java jdk后,可能要些时间生效。

    特别是程序调用java写的bat脚本时.

  6. SynergyS7G2RTC时钟模块的使用

    RTC功能描述 RTC时钟模块是Synergy芯片的一个时间外设,主要用于日期时间的存储和控制,有别于一般MCU中的Timer,RTC时钟有两种计时模式,日期模式和二进制计时模式,其中日期模式的时间可 ...

  7. Mysql 性能优化7【重要】sql语句的优化 浅谈MySQL中优化sql语句查询常用的30种方法(转)

    原文链接   http://www.jb51.net/article/39221.htm 这篇文章大家都在转载,估计写的有条理吧,本人稍微做一下补充 1.对查询进行优化,应尽量避免全表扫描,首先应考虑 ...

  8. C++进阶--命名空间和关键字using

    //############################################################################ /* * C++关键字:using * * ...

  9. 【Graphite学习】系列学习文章-【转】

    Graphite 系列 #2:Carbon 和 Whisper GRAPHITE SERIES #1: PROVISION HARDWARE GRAPHITE SERIES #2: CARBON &a ...

  10. 【Shell】使用sed命令替换文件中的某一行

    原始文件内容 -bash-3.2# cat configTest.xml <?xml version="1.0" encoding="UTF-8"?> ...