在MySQL中,行列转换是一种常见的操作。它包括行转列和列转行两种情况。
SELECT aggregated_column, [pivot_value_1], [pivot_value_2], ..., [pivot_value_n]
FROM (select...) AS source_table
PIVOT ( aggregate_function (column_for_aggregation)
FOR column_for_pivot IN ([pivot_value_1], [pivot_value_2], ..., [pivot_value_n]) ) AS pivot_table;
DROP TABLE IF EXISTS `stu`;
CREATE TABLE `stu` (
`sname` varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
`sub` varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
`score` varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of stu
-- ----------------------------
INSERT INTO `stu` VALUES ('zs', 'chinese', '100');
INSERT INTO `stu` VALUES ('zs', 'math', '99');
INSERT INTO `stu` VALUES ('zs', 'english', '98');
INSERT INTO `stu` VALUES ('li', 'chinese', '80');
INSERT INTO `stu` VALUES ('li', 'math', '89');
INSERT INTO `stu` VALUES ('li', 'english', '88');
INSERT INTO `stu` VALUES ('ww', 'chinese', '70');
INSERT INTO `stu` VALUES ('ww', 'math', '79');
INSERT INTO `stu` VALUES ('ww', 'english', '78');
SET FOREIGN_KEY_CHECKS = 1;
初始化数据:?
现在进行行列转换:
select sname,
case sub when "chinese" then score end "语文",
case sub when "math" then score end "数学",
case sub when "english" then score end "英语"
from stu;
?
?现在进行分组统计,然后合并:
select sname,
max(case sub when "chinese" then score end) "语文",
min(case sub when "math" then score end) "数学",
avg(case sub when "english" then score end) "英语"
from stu
GROUP BY sname;
现在行列转化已经完成!
行转化为列:
小结:case [列名] when [条件] then [数据] end
人员情况表(employee)中字段包括,员工号(ID),姓名(name),年龄(age),文化程度(wh):
包括四种情况(本科以上,大专,高中,初中以下),
现在我要根据年龄字段查询统计出:
表中文化程度为本科以上,大专,高中,初中以下,各有多少人,占总人数多少。
结果如下A:
学历 年龄 人数 百分比
本科以上 20 34 14
大专 20 33 13
高中 20 33 13
初中以下 20 100 40
本科以上 21 50 20
。。。。。。
SQL 查询语句如何写?
create table employee(id int primary key auto_increment,
name varchar(20),
age int(2),
wh varchar(20)
) ;
insert into employee(id,name,age,wh) values (null,'a',20,'本科以上') ;
insert into employee(id,name,age,wh) values (null,'b',20,'本科以上') ;
insert into employee(id,name,age,wh) values (null,'c',21,'本科以上') ;
insert into employee(id,name,age,wh) values (null,'d',20,'本科以上') ;
insert into employee(id,name,age,wh) values (null,'e',20,'大专') ;
insert into employee(id,name,age,wh) values (null,'e',21,'大专') ;
insert into employee(id,name,age,wh) values (null,'e',21,'高中') ;
insert into employee(id,name,age,wh) values (null,'e',20,'高中') ;
insert into employee(id,name,age,wh) values (null,'e',20,'初中以下') ;
?起始数据:
通过wh[文化]、age[年龄]分组,即可统计出来:?
select wh '学历',age '年龄',count(*) '人数', round((count(*)/(select count(0) from employee)) * 100) '百分比'
from employee
GROUP BY wh ,age
ORDER BY age;
-- 8:00--12:00 为迟到, 12:00--18:00 为早退
-- 打卡表 card
create table card(
cid int(10),
ctime timestamp ,
cuser int(10)
);
-- 人员表 person
create table person(
pid int(10),
name varchar(10)
) ;
-- 插入人员表的数据
insert into person values(1,'a');
insert into person values(2,'b');
-- 插入打卡的数据
insert into card values(1,'2009-07-19 08:02:00',1);
insert into card values(2,'2009-07-19 18:02:00',1);
insert into card values(3,'2009-07-19 09:02:00',2);
insert into card values(4,'2009-07-19 17:02:00',2);
insert into card values(5,'2009-07-20 08:02:00',1);
insert into card values(6,'2009-07-20 16:02:00',1);
insert into card values(7,'2009-07-20 07:02:00',2);
insert into card values(8,'2009-07-20 20:02:00',2);
-- 查询 迟到 早退的员工姓名?
查询结果如下:
工号 姓名 打卡日期 上班打卡 下班打卡 迟到 早退
1 a 2009-07-19 08:02:00 18:02:00 是 否
1 a 2009-07-20 08:02:00 16:02:00 是 是
2 b 2009-07-19 09:02:00 17:02:00 是 是
初始化表:?
?
-- 先查出每一个员工打卡的时间
select p.*,c.ctime
from person p join card c on c.cuser = p.pid;
-- 将日期格式化
select p.pid "工号",p.name "姓名",DATE_FORMAT(c.ctime,'%y-%m-%d') "打卡日期",DATE_FORMAT(c.ctime,'%h:%i:%s') "打卡时间"
from person p join card c on c.cuser = p.pid;
-- 将日期分离成上下午
select p.pid "工号",p.name "姓名",DATE_FORMAT(c.ctime,'%y-%m-%d') "打卡日期",DATE_FORMAT(c.ctime,'%h:%i:%s') "打卡时间"
from person p join card c on c.cuser = p.pid