SQL CROSS APPLY OUTER APPLY PIVOT UNPIVOT

set nocount on

--> 测试数据:[ta]

if object_id('[ta]') is not null drop table [ta]

go

create table [ta]([id] int,[name] varchar(1))

insert [ta]

select 1,'a'union all

select 2,'b'union all

select 3,'c'union all

select 4,'d'

--> 测试数据:[tb]

if object_id('[tb]') is not null drop table [tb]

go

create table [tb]([id] int,[name] varchar(2))

insert [tb]

select 1,'ff'union all

select 1,'yy'union all

select 1,'yf'union all

select 2,'xx'union all

select 2,'oo'union all

select 3,'xo'union all

select 5,'fy'

--------------开始查询--------------------------

--SQL 2005 新的表运算符apply pivot unpivot

--apply 涉及到下面两个步骤的子集(取决于apply 的类型)

--1、把右表表达式应用到左表输入的行

--2、添加外部行

--使用apply时,就好像先计算左输入,然后为左输入中的每一行计算一次右输入。

--cross apply outer apply的区别在于前者的外部(左侧)在内部(右侧)

--找不到对应航的时候不返回,后者则返回null

--看下面的例子

select * from[ta] a cross apply(select * from tb b where a.[id]=b.[id] )c

select * from[ta] a outer apply(select * from tb b where a.[id]=b.[id] )c

--cross apply 很重要的一个应用就是可以用来返回前N

select c.*from [ta] a cross apply(select top 2 * from tb b where a.[id]=b.[id] order by b.name )c

--pivot 包含下面三个逻辑

--1、隐式分组

--2、隔离值

--3、聚合函数

select * fromtb pivot(count(id) for [id] in([1],[2],[3])) as p

--unpivot

--UNPIVOT PIVOT 执行相反的操作,将表值表达式的列转换为列值。

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

--假设以上示例中生成的表在数据库中存储为pvt

--并且您需要将列标识符Emp1Emp2Emp3Emp4 Emp5 旋转为对应于特定供应商的行值。

--这意味着必须标识另外两个列。包含要旋转的列值(Emp1Emp2...)的列将被称为Employee

--将保存当前位于待旋转列下的值的列被称为Orders。这些列分别对应于

-- Transact-SQL 定义中的pivot_column value_column。以下为该查询。

CREATE TABLE pvt(VendorID int, Emp1 int, Emp2 int,

Emp3 int, Emp4 int, Emp5 int);

GO

INSERT INTO pvt VALUES (1,4,3,5,4,4);

INSERT INTO pvt VALUES (2,4,1,5,5,5);

INSERT INTO pvt VALUES (3,4,3,5,4,4);

INSERT INTO pvt VALUES (4,4,2,5,5,4);

INSERT INTO pvt VALUES (5,5,1,5,5,5);

GO

--select * from pvt

--Unpivot the table.

SELECT VendorID, Employee, Orders

FROM pvt

UNPIVOT(

Orders FOR Employee IN(Emp1, Emp2, Emp3, Emp4, Emp5)

)AS unpvt

GO

--请注意,UNPIVOT 并不完全是PIVOT 的逆操作。PIVOT 会执行一次聚合,

--从而将多个可能的行合并为输出中的单个行。

--UNPIVOT 不会重现原始表值表达式的结果,因为行已经被合并了。

--另外,UNPIVOT 的输入中的空值不会显示在输出中,

--而在执行PIVOT 操作之前,输入中可能有原始的空值。

--PIVOT UNPIVOT 在语法上可能让人很难理解,不过用得多了就熟悉了也就理解了

你可能感兴趣的:(apply)