当前位置:   article > 正文

Mysql学习——行与列的多种转换_mysql行转列

mysql行转列

目录

一、行转列

二、列转行

三、多列转一行

四、一行转多列

五、行转列的其案例


首先准备一张表

  1. CREATE TABLE CJ
  2. (
  3. Name varchar(32),
  4. Subject varchar(32),
  5. Result int(10)
  6. );
  7. # 插入数据
  8. insert into cj
  9. values ('张三', '语文', 80),
  10. ('张三', '数学', 90),
  11. ('张三', '物理', 85),
  12. ('李四', '语文', 85),
  13. ('李四', '数学', 92),
  14. ('李四', '物理', 82);

一、行转列

第一步,先将科目分类好:

  1. SELECT Name,
  2. CASE WHEN Subject='语文' THEN Result ELSE 0 END AS 语文,
  3. CASE WHEN Subject='数学' THEN Result ELSE 0 END AS 数学,
  4. CASE WHEN Subject='物理' THEN Result ELSE 0 END AS 物理
  5. FROM cj;

第二步:将上面的结果看做一张表,从表中找出每一个新字段的最大值,对Name进行分组

  1. SELECT T.Name,
  2. MAX(T.语文) 语文,
  3. MAX(T.数学) 数学,
  4. MAX(T.物理) 物理
  5. FROM (SELECT Name,
  6. CASE WHEN Subject='语文' THEN Result ELSE 0 END AS 语文,
  7. CASE WHEN Subject='数学' THEN Result ELSE 0 END AS 数学,
  8. CASE WHEN Subject='物理' THEN Result ELSE 0 END AS 物理
  9. FROM cj) T
  10. GROUP BY T.Name;

案例二:查询用户安装APP的情况

  1. create table app
  2. (
  3. id int,
  4. app varchar(32)
  5. );
  6. insert into app(id, app)
  7. VALUES (1, '微信'),
  8. (2, '快手'),
  9. (3, 'QQ'),
  10. (4, '抖音'),
  11. (5, '美团'),
  12. (6, '饿了么'),
  13. (7, '支付宝'),
  14. (8, '拼多多'),
  15. (9, '高德地图');
  16. CREATE TABLE app_install
  17. (
  18. uid int,
  19. app varchar(32)
  20. );
  21. insert into app_install(uid, app)
  22. VALUES (1, '微信'),
  23. (1, '美团'),
  24. (2, '支付宝'),
  25. (2, '高德地图'),
  26. (3, '拼多多');
  27. select uid,
  28. case when app = '微信' then 1 else 0 end as 'wx',
  29. case when app = '快手' then 1 else 0 end as 'ks',
  30. case when app = 'QQ' then 1 else 0 end as 'qq',
  31. case when app = '抖音' then 1 else 0 end as 'dy',
  32. case when app = '美团' then 1 else 0 end as 'mt',
  33. case when app = '饿了么' then 1 else 0 end as 'elm',
  34. case when app = '支付宝' then 1 else 0 end as 'zfb',
  35. case when app = '拼多多' then 1 else 0 end as 'pdd',
  36. case when app = '高德地图' then 1 else 0 end as 'gd'
  37. from app_install;
  38. select t.uid,
  39. case when max(t.wx) then '已安装' else '未安装' end as 'wx',
  40. case when max(t.ks) then '已安装' else '未安装' end as 'ks',
  41. case when max(t.qq) then '已安装' else '未安装' end as 'qq',
  42. case when max(t.dy) then '已安装' else '未安装' end as 'dy',
  43. case when max(t.mt) then '已安装' else '未安装' end as 'mt',
  44. case when max(t.elm) then '已安装' else '未安装' end as 'eml',
  45. case when max(t.zfb) then '已安装' else '未安装' end as 'zfb',
  46. case when max(t.pdd) then '已安装' else '未安装' end as 'pdd',
  47. case when max(t.gd) then '已安装' else '未安装' end as 'gd'
  48. from (select uid,
  49. case when app = '微信' then 1 else 0 end as 'wx',
  50. case when app = '快手' then 1 else 0 end as 'ks',
  51. case when app = 'QQ' then 1 else 0 end as 'qq',
  52. case when app = '抖音' then 1 else 0 end as 'dy',
  53. case when app = '美团' then 1 else 0 end as 'mt',
  54. case when app = '饿了么' then 1 else 0 end as 'elm',
  55. case when app = '支付宝' then 1 else 0 end as 'zfb',
  56. case when app = '拼多多' then 1 else 0 end as 'pdd',
  57. case when app = '高德地图' then 1 else 0 end as 'gd'
  58. from app_install) t
  59. group by t.uid;

连表比子查询要好  

二、列转行

建表

  1. CREATE TABLE CJ2
  2. (
  3. Name varchar(32),
  4. `语文` int(10),
  5. `数学` int(10),
  6. `物理` int(10)
  7. );
  8. # 插入数据
  9. insert into cj2 values ('张三',80,90,90),('李四',85,92,92);

原表:

  1. SELECT Name,'语文' cource,语文 result
  2. FROM cj2
  3. union all
  4. SELECT Name,'数学' cource,数学 result
  5. FROM cj2
  6. union all
  7. SELECT Name,'物理' cource,物理 result
  8. FROM cj2;
  9. # 查询后按照结果排序
  10. SELECT *
  11. FROM (SELECT Name,'语文' cource,语文 result
  12. FROM cj2
  13. union all
  14. SELECT Name,'数学' cource,数学 result
  15. FROM cj2
  16. union all
  17. SELECT Name,'物理' cource,物理 result
  18. FROM cj2) T
  19. ORDER BY T.Name;

三、多列转一行

将科目与分数排在一列

  1. SELECT Name,GROUP_CONCAT(Subject,':',Result) 成绩
  2. FROM cj
  3. group by Name;

 

四、一行转多列

将上表还原

  1. # 建表
  2. CREATE TABLE CJ3
  3. (
  4. Name varchar(32),
  5. `成绩` varchar(50)
  6. );
  7. # 插入数据
  8. insert into cj3
  9. values ('张三', '语文:80,数学:90,物理:85'),
  10. ('李四', '语文:85,数学:92,物理:82');

  1. SELECT Name,
  2. CASE
  3. WHEN LOCATE('语文', 成绩) > 0 THEN SUBSTRING_INDEX(SUBSTRING_INDEX(成绩, '语文:', -1), ',', 1)
  4. else 0 end as 语文,
  5. CASE
  6. WHEN LOCATE('数学', 成绩) > 0 THEN SUBSTRING_INDEX(SUBSTRING_INDEX(成绩, '数学:', -1), ',', 1)
  7. else 0 end as 数学,
  8. CASE
  9. WHEN LOCATE('物理', 成绩) > 0 THEN SUBSTRING_INDEX(SUBSTRING_INDEX(成绩, '物理:', -1), ',', 1)
  10. else 0 end as 物理
  11. from cj3;

  1. SELECT T1.Name, '语文' Cource, T1.语文 result
  2. FROM (SELECT Name,
  3. CASE
  4. WHEN LOCATE('语文', 成绩) > 0 THEN SUBSTRING_INDEX(SUBSTRING_INDEX(成绩, '语文:', -1), ',', 1)
  5. else 0 end as 语文
  6. from cj3) T1
  7. union all
  8. SELECT T2.Name, '数学' Cource, T2.数学 result
  9. FROM (SELECT Name,
  10. CASE
  11. WHEN LOCATE('数学', 成绩) > 0 THEN SUBSTRING_INDEX(SUBSTRING_INDEX(成绩, '数学:', -1), ',', 1)
  12. else 0 end as 数学
  13. from cj3) T2
  14. union all
  15. SELECT T3.Name, '物理' Cource, T3.物理 result
  16. FROM (SELECT Name,
  17. CASE
  18. WHEN LOCATE('物理', 成绩) > 0 THEN SUBSTRING_INDEX(SUBSTRING_INDEX(成绩, '物理:', -1), ',', 1)
  19. else 0 end as 物理
  20. from cj3) T3;

  1. SELECT *
  2. FROM (SELECT T1.Name, '语文' Cource, T1.语文 result
  3. FROM (SELECT Name,
  4. CASE
  5. WHEN LOCATE('语文', 成绩) > 0 THEN SUBSTRING_INDEX(SUBSTRING_INDEX(成绩, '语文:', -1), ',', 1)
  6. else 0 end as 语文
  7. from cj3) T1
  8. union all
  9. SELECT T2.Name, '数学' Cource, T2.数学 result
  10. FROM (SELECT Name,
  11. CASE
  12. WHEN LOCATE('数学', 成绩) > 0 THEN SUBSTRING_INDEX(SUBSTRING_INDEX(成绩, '数学:', -1), ',', 1)
  13. else 0 end as 数学
  14. from cj3) T2
  15. union all
  16. SELECT T3.Name, '物理' Cource, T3.物理 result
  17. FROM (SELECT Name,
  18. CASE
  19. WHEN LOCATE('物理', 成绩) > 0 THEN SUBSTRING_INDEX(SUBSTRING_INDEX(成绩, '物理:', -1), ',', 1)
  20. else 0 end as 物理
  21. from cj3) T3) T
  22. ORDER BY T.Name;

五、行转列的其他案例

准备一张result表

行转列

  1. # 查询1000号学生四门科目的成绩
  2. select StudentNo,
  3. case when SubjectNo = 1 then StudentResult else 0 end as 高等数学1,
  4. case when SubjectNo = 2 then StudentResult else 0 end as 高等数学2,
  5. case when SubjectNo = 3 then StudentResult else 0 end as java编程,
  6. case when SubjectNo = 4 then StudentResult else 0 end as hadoop理论
  7. from result
  8. where StudentNo = 1000;

  1. # 简化
  2. select StudentNo, MAX(高等数学1) math1, MAX(高等数学2) math2, MAX(java编程) java, MAX(hadoop理论) hadoop
  3. from (select StudentNo,
  4. case when SubjectNo = 1 then StudentResult else 0 end as 高等数学1,
  5. case when SubjectNo = 2 then StudentResult else 0 end as 高等数学2,
  6. case when SubjectNo = 3 then StudentResult else 0 end as java编程,
  7. case when SubjectNo = 4 then StudentResult else 0 end as hadoop理论
  8. from result
  9. where StudentNo = 1000) T;

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/461343
推荐阅读
相关标签
  

闽ICP备14008679号