Mysql行与列的多种转换(行转列,列转行,多列转一行,一行转多列)

 更新时间:2023年08月24日 09:53:01   作者:雷神乐乐  
在MySQL中,行转列和列转行都是非常有用的操作,本文就来介绍一下Mysql行与列的多种转换,主要包括行转列,列转行,多列转一行,一行转多列,具有一定的参考价值,感兴趣的可以了解一下

首先准备一张表

CREATE TABLE CJ
(
    Name    varchar(32),
    Subject varchar(32),
    Result  int(10)
);
# 插入数据
insert into cj
values ('张三', '语文', 80),
       ('张三', '数学', 90),
       ('张三', '物理', 85),
       ('李四', '语文', 85),
       ('李四', '数学', 92),
       ('李四', '物理', 82);

一、行转列

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

SELECT Name,
       CASE WHEN Subject='语文' THEN Result ELSE 0 END AS 语文,
       CASE WHEN Subject='数学' THEN Result ELSE 0 END AS 数学,
       CASE WHEN Subject='数学' THEN Result ELSE 0 END AS 物理
FROM cj;

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

SELECT T.Name,
       MAX(T.语文) 语文,
       MAX(T.数学) 数学,
       MAX(T.物理) 物理
FROM (SELECT Name,
       CASE WHEN Subject='语文' THEN Result ELSE 0 END AS 语文,
       CASE WHEN Subject='数学' THEN Result ELSE 0 END AS 数学,
       CASE WHEN Subject='数学' THEN Result ELSE 0 END AS 物理
FROM cj) T
GROUP BY T.Name;

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

create table app
(
    id  int,
    app varchar(32)
);
insert into app(id, app)
VALUES (1, '微信'),
       (2, '快手'),
       (3, 'QQ'),
       (4, '抖音'),
       (5, '美团'),
       (6, '饿了么'),
       (7, '支付宝'),
       (8, '拼多多'),
       (9, '高德地图');
CREATE TABLE app_install
(
    uid int,
    app varchar(32)
);
insert into app_install(uid, app)
VALUES (1, '微信'),
       (1, '美团'),
       (2, '支付宝'),
       (2, '高德地图'),
       (3, '拼多多');
select uid,
       case when app = '微信' then 1 else 0 end as 'wx',
       case when app = '快手' then 1 else 0 end as 'ks',
       case when app = 'QQ' then 1 else 0 end as 'qq',
       case when app = '抖音' then 1 else 0 end as 'dy',
       case when app = '美团' then 1 else 0 end as 'mt',
       case when app = '饿了么' then 1 else 0 end as 'elm',
       case when app = '支付宝' then 1 else 0 end as 'zfb',
       case when app = '拼多多' then 1 else 0 end as 'pdd',
       case when app = '高德地图' then 1 else 0 end as 'gd'
from app_install;
select t.uid,
       case when max(t.wx) then '已安装' else '未安装' end as 'wx',
       case when max(t.ks) then '已安装' else '未安装' end as 'ks',
       case when max(t.qq) then '已安装' else '未安装' end as 'qq',
       case when max(t.dy) then '已安装' else '未安装' end as 'dy',
       case when max(t.mt) then '已安装' else '未安装' end as 'mt',
       case when max(t.elm) then '已安装' else '未安装' end as 'eml',
       case when max(t.zfb) then '已安装' else '未安装' end as 'zfb',
       case when max(t.pdd) then '已安装' else '未安装' end as 'pdd',
       case when max(t.gd) then '已安装' else '未安装' end as 'gd'
from  (select uid,
       case when app = '微信' then 1 else 0 end as 'wx',
       case when app = '快手' then 1 else 0 end as 'ks',
       case when app = 'QQ' then 1 else 0 end as 'qq',
       case when app = '抖音' then 1 else 0 end as 'dy',
       case when app = '美团' then 1 else 0 end as 'mt',
       case when app = '饿了么' then 1 else 0 end as 'elm',
       case when app = '支付宝' then 1 else 0 end as 'zfb',
       case when app = '拼多多' then 1 else 0 end as 'pdd',
       case when app = '高德地图' then 1 else 0 end as 'gd'
from app_install) t
group by t.uid;

连表比子查询要好  

二、列转行

建表

CREATE TABLE CJ2
(
    Name varchar(32),
    `语文` int(10),
    `数学` int(10),
    `物理` int(10)
);
# 插入数据
insert into cj2 values ('张三',80,90,90),('李四',85,92,92);

原表:

SELECT Name,'语文' cource,语文 result
FROM cj2
union all
SELECT Name,'数学' cource,数学 result
FROM cj2
union all
SELECT Name,'物理' cource,物理 result
FROM cj2;
# 查询后按照结果排序
SELECT *
FROM (SELECT Name,'语文' cource,语文 result
FROM cj2
union all
SELECT Name,'数学' cource,数学 result
FROM cj2
union all
SELECT Name,'物理' cource,物理 result
FROM cj2) T
ORDER BY T.Name;

三、多列转一行

将科目与分数排在一列

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

 

四、一行转多列

将上表还原

# 建表
CREATE TABLE CJ3
(
    Name varchar(32),
    `成绩` varchar(50)
);
# 插入数据
insert into cj3
values ('张三', '语文:80,数学:90,物理:85'),
       ('李四', '语文:85,数学:92,物理:82');

SELECT Name,
       CASE
           WHEN LOCATE('语文', 成绩) > 0 THEN SUBSTRING_INDEX(SUBSTRING_INDEX(成绩, '语文:', -1), ',', 1)
           else 0 end as 语文,
       CASE
           WHEN LOCATE('数学', 成绩) > 0 THEN SUBSTRING_INDEX(SUBSTRING_INDEX(成绩, '数学:', -1), ',', 1)
           else 0 end as 数学,
       CASE
           WHEN LOCATE('物理', 成绩) > 0 THEN SUBSTRING_INDEX(SUBSTRING_INDEX(成绩, '物理:', -1), ',', 1)
           else 0 end as 物理
from cj3;

SELECT T1.Name, '语文' Cource, T1.语文 result
FROM (SELECT Name,
             CASE
                 WHEN LOCATE('语文', 成绩) > 0 THEN SUBSTRING_INDEX(SUBSTRING_INDEX(成绩, '语文:', -1), ',', 1)
                 else 0 end as 语文
      from cj3) T1
union all
SELECT T2.Name, '数学' Cource, T2.数学 result
FROM (SELECT Name,
             CASE
                 WHEN LOCATE('数学', 成绩) > 0 THEN SUBSTRING_INDEX(SUBSTRING_INDEX(成绩, '数学:', -1), ',', 1)
                 else 0 end as 数学
      from cj3) T2
union all
SELECT T3.Name, '物理' Cource, T3.物理 result
FROM (SELECT Name,
             CASE
                 WHEN LOCATE('物理', 成绩) > 0 THEN SUBSTRING_INDEX(SUBSTRING_INDEX(成绩, '物理:', -1), ',', 1)
                 else 0 end as 物理
      from cj3) T3;

SELECT *
FROM (SELECT T1.Name, '语文' Cource, T1.语文 result
FROM (SELECT Name,
             CASE
                 WHEN LOCATE('语文', 成绩) > 0 THEN SUBSTRING_INDEX(SUBSTRING_INDEX(成绩, '语文:', -1), ',', 1)
                 else 0 end as 语文
      from cj3) T1
union all
SELECT T2.Name, '数学' Cource, T2.数学 result
FROM (SELECT Name,
             CASE
                 WHEN LOCATE('数学', 成绩) > 0 THEN SUBSTRING_INDEX(SUBSTRING_INDEX(成绩, '数学:', -1), ',', 1)
                 else 0 end as 数学
      from cj3) T2
union all
SELECT T3.Name, '物理' Cource, T3.物理 result
FROM (SELECT Name,
             CASE
                 WHEN LOCATE('物理', 成绩) > 0 THEN SUBSTRING_INDEX(SUBSTRING_INDEX(成绩, '物理:', -1), ',', 1)
                 else 0 end as 物理
      from cj3) T3) T
ORDER BY T.Name;

五、行转列的其他案例

准备一张result表

行转列

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

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

 到此这篇关于Mysql行与列的多种转换(行转列,列转行,多列转一行,一行转多列)的文章就介绍到这了,更多相关Mysql行与列转换内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • mysql中的四大运算符种类实例汇总(20多项) 

    mysql中的四大运算符种类实例汇总(20多项) 

    这篇文章主要介绍了mysql中的四大运算符种类汇总,运算符连接表达式中的各个操作数,他的作用是用来指明对数据表中的操作数所进行的运算
    2022-07-07
  • Mysql全文搜索match against的用法

    Mysql全文搜索match against的用法

    全文检索在 MySQL 中就是一个 FULLTEXT 类型索引。FULLTEXT 索引用于 MyISAM 表,可以在 CREATE TABLE 时或之后使用 ALTER TABLE 或 CREATE INDEX 在 CHAR、 VARCHAR 或 TEXT 列上创建
    2011-10-10
  • MySQL数据库优化技术之配置技巧总结

    MySQL数据库优化技术之配置技巧总结

    这篇文章主要介绍了MySQL数据库优化技术之配置技巧,较为详细的总结分析了MySQL进行硬件级软件优化的相关方法与注意事项,需要的朋友可以参考下
    2016-07-07
  • 关于mysql数据库格式化简单介绍

    关于mysql数据库格式化简单介绍

    本文将介绍关于mysql数据库格式化时需要注意的一些问题,需要的朋友可以参考下
    2012-11-11
  • Mysql临时变量的具体使用

    Mysql临时变量的具体使用

    本文主要介绍了Mysql临时变量的具体使用,临时变量有分为用户变量和会话变量,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-08-08
  • mysql实现本地keyvalue数据库缓存示例

    mysql实现本地keyvalue数据库缓存示例

    这篇文章主要介绍了代码实现本地Key-Value缓存示例,大家参考使用吧
    2013-12-12
  • MySQL redo死锁问题排查及解决过程分析

    MySQL redo死锁问题排查及解决过程分析

    被告知在多实例场景下 MySQL Server hang 住,无法测试下去,原生版本不存在这个问题,而新版本上出现了这个问题,不禁心头一颤,心中不禁感到奇怪,还好现场环境还在,为排查问题提供了一个好的环境,随即便投入到紧张的问题排查过程当中
    2016-10-10
  • MySQL语句整理及汇总介绍

    MySQL语句整理及汇总介绍

    今天小编就为大家分享一篇关于MySQL语句整理及汇总介绍,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • MySQL将一个字段中以逗号分隔的取出来形成新的字段实现

    MySQL将一个字段中以逗号分隔的取出来形成新的字段实现

    这篇文章主要介绍了MySQL将一个字段中以逗号分隔的取出来形成新的字段实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-10-10
  • 关于MYSQL 你需要知道的数据类型和操作数据表

    关于MYSQL 你需要知道的数据类型和操作数据表

    这篇文章主要介绍了关于MYSQL中数据类型的知识和操作数据表的方法,文中讲解非常详细供大家参考学习,感兴趣的朋友可以了解下
    2020-06-06

最新评论