1、透视原理:就是将查询结果进行转置
下面就举例来说明:
执行下面语句:检查是否含有表 dbo.Orders,如果有就将表删除:
if OBJECT_ID('dbo.Orders','U') is not null
drop table dbo.Orders
然后创建表dbo.Orders:
create table dbo.Orders
(
orderid int not null primary key,
empid int not null,
custid int not null,
orderdate datetime,
qty int
)
批量插入数据:
insert into dbo.Orders (orderid,orderdate,empid,custid,qty) values
(30001,'',3,1,10),
(10001,'',2,1,12),
(10005,'',1,2,20),
(40001,'',2,3,40),
(20001,'',2,2,12),
(10006,'',1,3,14),
(40005,'',3,1,10),
(20002,'',1,3,20),
(30003,'',2,2,15),
(30004,'',3,3,22),
(30007,'',3,4,30)
业务逻辑:查询出 每个 员工 处理的 每个客户的 订单总数
普通的查询方式:
select
empid,custid,SUM(qty) as sumqty
from Orders
group by empid,custid
order by empid
查询结果:
但是现在想要的结果是:
其中的A、B、C分别代表三个 客户Id,需要将原来的结果进行转置。
实现上面的结果就是sql里面的透视:
三个步骤:
1、将结果数据进行分组
2、将结果数据进行扩展
3、将结果数据进行聚合
第一种是实现方式:复杂、简单易懂的方式:使用相关子查询:
select
empid,
--下面是相关子查询,不是表的连接
(
select
SUM(qty)
from Orders as innerO
where innerO.empid=outerO.empid and custid=1
group by innerO.empid
) as A ,
(
select
SUM(qty)
from Orders as innerO
where innerO.empid=outerO.empid and custid=2
group by innerO.empid
) as B ,
(
select
SUM(qty)
from Orders as innerO
where innerO.empid=outerO.empid and custid=3
group by innerO.empid
) as C
from Orders as outerO
group by empid
第二种实现方式:使用组函数的特殊用法:
--简单方式 :使用sum()函数的特殊用法:在方法里面,添加 case语句
select
empid,
SUM(case when custid=1 then qty end) as A,--这样 将已经对empid 进行了限制
SUM(case when custid=2 then qty end) as B,
SUM(case when custid=3 then qty end) as C,
SUM(qty) as sumqty
from Orders
group by empid
第三种方式:使用pivot,是 sql server 特有的,在oracle里面没有:
select
empid,[],[],[]
from
(
--仅仅查询出 在 透视 里面需要用到的数据
select
empid,custid,qty
from Orders
) as t --在这里已经对数据 进行了分组
pivot
(
sum(qty) --聚合函数 (对那个列 执行 组函数)
for custid in ([],[],[])-- (对那些数据进行了聚合运算) 这里的数字一定要 加[]因为
) as p
这种 使用 sql server 里面内置的 pivot 的方法,肯定是比上面两种自己写的方法的效率高。