PIVOT 通过将表达式某一列中的唯一值转换为输出中的多个列来旋转表值表达式,并在必要时对最终输出中所需的任何其余列值执行聚合。提供的语法比在SQL Server 2000用聚合函数配合CASE语句实现的语法更简单和更具可读性。在我们进行复杂的查询统计的时候,特别是销售统计、处理大量数据的时候,PIVOT的作用就显得非常突出。
注意:PIVOT、UNPIVOT是SQL Server 2005 的语法,使用需修改数据库兼容级别
在数据库属性->选项->兼容级别改为 90
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语法可以分为三步理解:
1. 原始的查询语句
2.定义行转列
3.根据行转列的数据,呈现结果
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 目的:统计各关注数据(ldap_sts)的数量。 select * ---- 第三步:把PIVOT好的資料直接呈現出來。 from ( select [ldap_id], [ldap_sts] from ccldap ---- 第一步:原始查询。 ------只选取了ID的关注列 ) S ---- 一定要有,会报语法错误。 pivot ( count([ldap_id]) --- 统计 for [ldap_sts] in ([1],[2],[3],[4],[5],[6],[7]) ---- 为各状态进行统计。 ---- 注意:[1][2]…[7]是[ldap_sts]的值,以状态位表示法來描述[ldap_sts]的值。 ) P ---- 一定要有,不然会有语法错误。
1 2 3 4 5 6 7 <---关注数据 --------- --------- --------- --------- --------- --------- --------- 1 12528 68519 120 8 5 36 <---数量
案例二:
--## 二維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
下面是执行结果:
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
UNPIVOT 与 PIVOT 执行相反的操作,将表值表达式的列转换为列值。但是在实际应用中,有些聚合之后的数据很难进行拆分。所以呢,UNPIVOT并非PIVOT的逆过程。