做数据统计时通常需要行转列:
把表中特定列的数据行去重后做为列名,把数据行转化为数据列。三种数据库都可以通过case when 语句实现行转列。
下面以每人拥有的各种酒的数量表 演示行转列语法:
create table line2column (username varchar(30),commodity varchar(30),num int );
insert into line2column
VALUES('张三','啤酒',14);
insert into line2column
VALUES('张三','白酒',2);
insert into line2column
VALUES('张三','葡萄酒',60);
insert into line2column
VALUES('张三','黄酒',20);
insert into line2column
VALUES('李四','啤酒',6);
insert into line2column
VALUES('李四','葡萄酒',16);
insert into line2column
VALUES('李四','黄酒',33);
insert into line2column
VALUES('王二','啤酒',14);
insert into line2column
VALUES('王二','白酒',25);
insert into line2column
VALUES('王二','黄酒',8);
select * from line2column;

-- case when行转列语法:
select username,
sum(case commodity when '啤酒' then num else 0 end) 啤酒,
sum(case commodity when '白酒' then num else 0 end) 白酒,
sum(case commodity when '葡萄酒' then num else 0 end) 葡萄酒,
sum(case commodity when '黄酒' then num else 0 end) 黄酒
from line2column
group by username;

三种数据库还都有各自的特殊语法来实现行转列:
oracle :
利用decode函数(将查询结果翻译成其他值)、聚集函数(sum,max,min),结合group by 分组实现
。行转列时,聚集函数的使用,一般非数字类型的字段不能用sum,可用max或min代替。
select username,
nvl(sum(decode(commodity, '啤酒', num)),0) 啤酒,
nvl(sum(decode(commodity, '白酒', NUM)),0) 白酒,
nvl(sum(decode(commodity, '葡萄酒', NUM)),0) 葡萄酒,
nvl(sum(decode(commodity, '黄酒', NUM)),0) 黄酒
from line2column
group by username;
sqlserver:
在2005以上版本中也可以直接使用pivot实现:
select * from
(select UserName,commodity,isnull(num,0) as num from line2column) test
pivot
(sum(num) for commodity in(啤酒,白酒,葡萄酒,黄酒)
) pvt
mysql的行转列语法:
SELECT DISTINCT a.username,
(SELECT num FROM line2column b WHERE a.username=b.username AND b.commodity='啤酒' ) AS '啤酒',
(SELECT num FROM line2column b WHERE a.username=b.username AND b.commodity='白酒' ) AS '白酒',
(SELECT num FROM line2column b WHERE a.username=b.username AND b.commodity='葡萄酒' ) AS '葡萄酒',
(SELECT num FROM line2column b WHERE a.username=b.username AND b.commodity='黄酒' ) AS '黄酒'
FROM line2column a;
这几种语法都是静态语句,只针对固定的行编列,如果要动态实现,可以使用动态sql存储过程,实现更灵活的行转列。
学习更多请扫描下方二维码,移步知识星球:





