IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> MYSQL 行转列、列转行、多列转一行、一行转多列 -> 正文阅读

[大数据]MYSQL 行转列、列转行、多列转一行、一行转多列

本篇博客是之前看到关于面试的一道SQL题 拿来学习了一下 看完看完本篇博客,相信你会对SQL语法有不一样的感觉和认识。

版本说明

mysql8.0

😍 一、行转列

🍀需求

🚩 经典case when实现

select

name,

max(case subject when '语文' then resuilt else 0 end) '语文',

max(case subject when '数学' then resuilt else 0 end) '数学',

max(case subject when '物理' then resuilt else 0 end) '物理'

from student group by name

🚩 使用if语句

大体同case when

select name,

max(if(subject = '语文',resuilt,0)) '语文'

from student group by name

🚩 动态拼接sql语句,不管多少行都会转列

set @sql = null;

select group_concat(distinct concat('max(if(a.subject = ''',a.subject,''', a.resuilt, 0)) as ''',a.subject, '''')) into @sql from student a;

set @sql = concat('select name,', @sql, 'from student a group by a.name' );

prepare stmt from @sql; -- 动态生成脚本,预备一个语句

execute stmt; -- 动态执行脚本,执行预备的语句

deallocate prepare stmt; -- 释放预备的语句

扩展分析

mysql的列转行为什么一定要用sum 或者max

遇到这种问题我们可以通过调试sql,来解决我们遇到的疑惑。

😍 二、列转行

🍀需求

转换为

select
name,
'语文' as subject,
chinese as resuilt
from -- 注意这里正常应该是from后直接跟一个表 偷懒不想创建表结构 直接用的子查询(行转列的代码)
(select
name,
max(case subject when '语文' then resuilt else 0 end) 'chinese',
max(case subject when '数学' then resuilt else 0 end) 'math',
max(case subject when '物理' then resuilt else 0 end) 'physics'
from student group by name
) t

union all

select
name,
'数学' as subject,
math as resuilt
from -- 注意这里正常应该是from后直接跟一个表 偷懒不想创建表结构 直接用的子查询(行转列的代码)
(select
name,
max(case subject when '语文' then resuilt else 0 end) 'chinese',
max(case subject when '数学' then resuilt else 0 end) 'math',
max(case subject when '物理' then resuilt else 0 end) 'physics'
from student group by name
) t

union all

select
name,
'物理' as subject,
physics as resuilt
from -- 注意这里正常应该是from后直接跟一个表 偷懒不想创建表结构 直接用的子查询(行转列的代码)
(select
name,
max(case subject when '语文' then resuilt else 0 end) 'chinese',
max(case subject when '数学' then resuilt else 0 end) 'math',
max(case subject when '物理' then resuilt else 0 end) 'physics'
from student group by name
) t

?

总结

行转列,使用case…when分情况查询数据,group by和sum/max进行筛选

列转行,查询需要的每列数据使用union或者union all求并集

😍 三、多列转一行

🍀需求

变为


select name,GROUP_CONCAT(`subject`,':',resuilt) '成绩' from student group by name

GROUP_CONCAT(expr)该函数将非空列值按照分组条件进行合并并最终返回。如果有空值,则返回为空

😍 四、一行转多列

🍀需求

变为

?a表

select 
name,
marks, 
case 
 when locate('语文',marks) > 0 then substring_index(substring_index(marks,'语文:',-1),',',1) else 0 end 
as 语文 ,
case 
 when locate('数学',marks) > 0 then substring_index(substring_index(marks,'数学:',-1),',',1) else 0 end 
as 数学 ,
case 
 when locate('物理',marks) > 0 then substring_index(substring_index(marks,'物理:',-1),',',1) else 0 end 
as 物理 ,
case 
 when locate('历史',marks) > 0 then substring_index(substring_index(marks,'历史:',-1),',',1) else 0 end 
as 历史 
from 
(select
name,
GROUP_CONCAT(subject,':',resuilt) marks
from
student group by name) a

上面只是第一步 举例 要求还差一步 使用union all 继续加工sql

b表

select
name,
'语文' subject,
语文 score
from 
(a表) b

union all

select
name,
'数学' subject,
数学 score
from 
(a表) b

union all

select
name,
'物理' subject,
物理 score
from 
(a表) b

union all

select
name,
'历史' subject,
历史 score
from 
(a表) b

Locate函数主要的作用是判断一个字符串是否包含另一个字符串,如

Locate(str,sub) > 0,表示sub字符串包含str字符串;

Locate(str,sub) = 0,表示sub字符串不包含str字符串。

substring_index(参数str,参数delim,参数count)

str :要处理的字符串

delim:分隔符

count:计数

也就是说,如果count是正数,那么就是从左往右数,第N个分隔符的左边的全部内容! 相反,如果是负数,那么就是从右边开始数,第N个分隔符右边的所有内容,

参考文章

mysql行转列,列转行,以及为什么行转列的时候用max函数_一朵风中摇曳的水仙花的博客-CSDN博客_max函数 行转列

浅析MySQL中concat以及group_concat的使用 - 程序员大本营

MySQL函数Locate的使用_今夜无风亦无雨的博客-CSDN博客_mysql的locate

MySQL中的substring_index()函数使用方法与技巧_极客小俊的博客-CSDN博客_mysql substring_index

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-06-14 22:40:05  更:2022-06-14 22:40:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 21:35:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码