【SQL应知应会】行列转换(二)• MySQL版

请添加图片描述

欢迎来到爱书不爱输的程序猿的博客, 本博客致力于知识分享,与更多的人进行学习交流

本文收录于SQL应知应会专栏,本专栏主要用于记录对于数据库的一些学习,有基础也有进阶,有MySQL也有Oracle

请添加图片描述

行列转换 • Mysql版

  • 前言
  • 一、MySQL行列转换
    • 1.数据准备操作
    • 2.行转列
      • 1.1为何进行行转列?
      • 1.2 行转列有两个意思:1.表内的行转列 2.跨表的行转列
    • 3.行转列的思路:行变少,列变多
      • 3.1 如何进行行转列:增加字段,进行聚合(行变少)
    • 4.行转列的实操
      • 4.1 通用的行转列(Mysql和Oracle都能用)
        • 4.1.1想在结果中加入学生名字
          • 4.1.1.1加入名字的方法1:
          • 4.1.1.1 加入名字的方法2:
      • 4.2 私有方法的行转列(Mysql用)
        • 4.2.1 添加名字的两种方法
    • 3.列转行
      • 3.1列转行思路:行变多 用union
      • 3.2 列转行实操
        • 3.2.1 数据准备
        • 3.2.2 实操
  • 小结

前言

在前一篇内容中,学习了MySQL的行列转换中的行转列,其中只讲述了在MySQL与Oracle中通欧诺个的行转列,并且进行了对应的扩展了——如果想在结果中加入学生姓名的方法,上一篇讲了其中一种方法,就是使用关联子查询。

今天这篇内容,将继续进行讲述MySQL的行列转换的后续内容,其中包括添加学生姓名的第二种方法(使用了join进行关联表),以及本文章主攻的核心内容——行列转换中的列转行。

同样的,为了大家可以更方便的一起跟着文章进行代码的操作学习,在文章中的每一块的知识点都提供了对应的数据准备,即大家可以直接复制代码在自己的电脑上进行建表,然后根据文章中的内容一起进行实操,因为我个人认为计算机方面的知识点的学习,实操相对于光进行文字的学习会更有效果,并且更容易发现自己的短板和思路中存在的问题。

那么,快拿出你的电脑,跟着文章一起学习起来吧

一、MySQL行列转换

1.数据准备操作

:传送门数据准备操作

2.行转列

1.1为何进行行转列?

:传送门1.1为何进行行转列?

1.2 行转列有两个意思:1.表内的行转列 2.跨表的行转列

:传送门1.2 行转列的两个意思

3.行转列的思路:行变少,列变多

3.1 如何进行行转列:增加字段,进行聚合(行变少)

:传送门3.1如何进行行转列

4.行转列的实操

4.1 通用的行转列(Mysql和Oracle都能用)

:传送门4.1通用的行转列(Mysql和Oracle都能用)

4.1.1想在结果中加入学生名字

:传送门4.1.1在结果中加入学生名字)

4.1.1.1加入名字的方法1:
4.1.1.1 加入名字的方法2:
select distinct t1.user_name ,t0.*    -- 如果不加distinct,因为t1表每个ID对应多个名字,所以最终结过就是,名字重复几次,结果就有几行重复
from
(
	select 
			user_id '学生ID',
			max(case when course = '语文' then score end) '语文',
			max(case when course = '数学' then score end) '数学',
			max(case when course = '英语' then score end) '英语'
	from 
			table_grade
	group by 
			user_id
) t0left join table_grade t1
on t0.学生ID  = t1.user_id;     -- 此处的t0.学生ID,因为前面设置了别名,所以此处也应该使用别名,不然就会发生错误:Unknown column 't0.user_id' in 'on clause'

4.2 私有方法的行转列(Mysql用)

select user_id '学生ID',
		 max(if(course = '语文',score,null)) '语文',
		 max(if(course = '数学',score,null)) '数学',
		 max(if(course = '英语',score,null)) '英语'
from table_grade
group by user_id 

4.2.1 添加名字的两种方法

select user_id '学生ID',
			(select max(user_name) from table_grade where table_grade.user_id =t.user_id ) user_name,
			max(if(course = '语文',score,null)) '语文',
			max(if(course = '数学',score,null)) '数学',
			max(if(course = '英语',score,null)) '英语'
from table_grade t
group by user_id 
select distinct t1.user_name,t0.*
from 
(	 select user_id '学生ID',
					max(if(course = '语文',score,null)) '语文',
					max(case when course = '数学' then score end) '数学',
					max(if(course = '英语',score,null)) '英语'
	 from table_grade  
	 group by user_id ) t0
left join table_grade t1
on t0.学生ID = t1.user_id;

3.列转行

	a	b	c             
1										  1   a
2                     1   b
3                     1   c
                      2   a
											2		b
											2		c 
											3		a
											3		b
											3		c

列转行如上图所示,左边变成右边

  • 右图又称为纵表,这种纵表在大数据中适合用工具hbase进行列式存储,里面存的就是键值对,右图的左列是键、右列是值
    • 纵表适合存储,横表适合分析
    • 底层明细数据,适合列式存储

3.1列转行思路:行变多 用union

  • select(查询)能表达的关系是并差交笛卡尔积
  • 集合运算是 并差交笛卡尔积
  • 关系运算是 投影连接除
  • 大数据一次处理一个集合(set),不是一个记录(record)

3.2 列转行实操

3.2.1 数据准备

  • 建个横表

    create table table_grade_wide as(
      	select user_id '学生ID',
      		max(if(course = '语文',score,null)) '语文',
      		max(if(course = '数学',score,null)) '数学',
      		max(if(course = '英语',score,null)) '英语'
      	from table_grade
      	group by user_id )
    
    alter table table_grade_wide change user_id id  int;
    

3.2.2 实操

select * from(
	select 学生ID,'语文' course,语文 score from table_grade_wide -- 只需要在第一个select字段中修改别名就好了,因为union的时候,前后的所有的select的列的类型和个数是一致的
	union   --
	select 学生ID,'数学',数学 from table_grade_wide
	union 
	select 学生ID,'英语',英语 from table_grade_wide ) a
where score is not null     -- 因为有的同学只考了其中几门课
order by 1;   -- 按照最后结果的第一列进行排序

小结

好了,MySQL的行列转换到这里就要告一段落了,希望大家通过上一篇文章——行列转换(一)• MySQL版以及本篇文章的学习,应该对MySQL的行列转换有了了解,学习是永无止境的,接下来,我们会按照这样的方式为大家讲述Oracle中的行列转换,如果大家对于文章的内容、排版等各个方面有什么好的想法,都可以进行沟通交流,也希望我的博客中的内容能为大家在学习的道路上提供一点点助力,我们一起学习,一起进步

【SQL应知应会】行列转换(二)• MySQL版_第1张图片

你可能感兴趣的:(SQL应知应会,mysql,adb,数据库,大数据,oracle,数据分析)