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

news2024/11/24 14:42:31

请添加图片描述

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

本文收录于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:

一、MySQL行列转换

1.准备操作

  • 先建一个表
create table table_grade(
id int,
user_name varchar(20),
course varchar(10),
score decimal(5,2)
);
  • 练习 三种插入
insert into table_grade(id,user_name,course,score) values (1,'张龙','语文','78'),(2,'张龙','数学','95'),(3,'张龙','英语','81');
insert into table_grade values(4,'赵虎','语文','97'),(5,'赵虎','数学','78'),(6,'赵虎','英语','91');
insert into table_grade set id = 7,user_name = '王五',course = '语文',score = '81';
insert into table_grade set id = 8,user_name = '王五',course = '数学',score = '55';
insert into table_grade set id = 9,user_name = '王五',course = '英语',score = '75';
insert into table_grade values(10,'马六','语文','87'),(11,'马六','数学','65'),(12,'马六','英语','75');
  • 修改列类型
alter table table_grade modify score decimal;  -- decimal默认10位整数

2.行转列

1.1为何进行行转列?

  • 现实中用到的一些数据是明细数据/流水账
    用户名 商品 购买时间
    A 手机 4.20
    A U盘 4.21
    B …
    B …

    • 如上,展示的就是明细数据,每个用户有多条商品的购买记录,这种明细数据称为【多用户集】,往往我们想换一种展示的方式,因为每个用户有多个数据,想把这种多用户的数据变成单用户数据,即【单用户集】,如下
      用户名 最近一次购买商品 最近两次购买商品 A U盘 手机
      B … …
      • 显然,单用户集展示的信息更多一点,对于上面的多用户集,如果一个用户拥有太多条信息,就会看着很乱,所以需要变成单用户集
      • 单用户集有个问题,就是列需要不断的增加,存储方面的开销会大一点,因为需要给它分配很多列的空间
      • 明细数据经常以如上所示的纵表的方式,所以又称为【纵表】,因为它的数据是以堆叠的方式显示的(一个用户有多条记录),即stack方式显示;单用户集是以列的方式显示的,又称为【横表】,所以将多用户集变成单用户集的方式又称为【行转列】或【unstack】过程
      • 行转列后的单用户集数据,更适合做数据分析,如上面的单用户集,可以很直观的看到最近一次或最近两次的购买数据,而如果是看上面的多用户集,还得根据时间去比较,才可以看到一些隐藏信息
      • 列转行,就是将单用户集再转回多用户集

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

  • 跨表就是假设除了购买商品的流水,还有其他的一些流水,也是与用户ID一起记录的,比如用户的积分表,也可以对上面的单用户集进行关联,使单用户集的列增多。经常将跨表的行转列,列变多的过程,称为拉宽的过程
  • 称上面那种购物明细表为【事实表】,多个事实表通过键关联,就会拉宽字段(维度+指标)
update table_grade set id = 4 where user_name = '马六'

alter table table_grade add oid varchar(10)

alter table table_grade modify oid varchar(50)

update table_grade set oid = uuid();  -- 设置一个代理键

alter table table_grade rename column id to user_id -- 修改某列名字

alter table table_grade modify oid varchar(50) first  -- 修改某列位置

show columns from table_grade;   -- 查看表各列

show keys from table_grade;   -- 查看索引

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

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

  • 通过聚合将多用户变成单用户,使用哪一个聚合函数与数据有关

  • 使用max()则选取最大的一条

  • 现在的表如下所示
    张龙 语文 78
    张龙 数学 95
    张龙 英语 81
  • 我们想显示成:
    语文 数学 英语
    张龙 78 95 81
  • 这样的话,张龙语文只能有一个成绩,若有多个成绩
    • ** 思路1:用列表把多个成绩放在一起 **
      语文 数学 英语
      张龙 78,88 95 81
    • ** 思路2:取一个最近的考试成绩(这就需要在表中加一个时间列)**
    • ** 思路3:如果两次成绩重复了,比如都是100,就可以用max或min**
      语文 数学 英语
      张龙 100 95 81
      • 如果用sum的话,统计结果就变成了200
        语文 数学 英语
        张龙 200 95 81
        - 增加一个时间限制
alter table table_grade add column exam_date date after score;
  • 设置随机时间
update table_grade set exam_date = date_format(from_unixtime(  -- from_unixtime() 将时间戳转换为日期,date_format()设置一下日期格式
unix_timestamp('2023-01-01')    -- 将日期转为一个时间戳,此处是用1月1号加随机的天数(由于天数是1月1到4月28,所以最终的结果不会超过4月28)
+ floor( rand() *               -- rand() 随机数[0,1),floor() 向下取整
		(unix_timestamp('2023-04-28') - unix_timestamp('2023-01-01') + 1) -- 4月28减去1月1号的天数,因为rand的范围是[0,1),所以后面+1是为了保证可以取得4月28
	) 
	),'%Y-%m-%d');

4.行转列的实操

  • 前提: 假设张龙各科只考了一次,对此进行行转列

    • 为了可以看出差异性,删除王五的英语,马六的语文
    delete from table_grade where user_name = '王五' and course = '英语';
    delete from table_grade where user_name = '马六' and course = '语文';
    

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

select user_id '学生ID', 
			 max(case when course = '语文' then score else null end) '语文',  -- 因为只有一个成绩,max min 没区别; else null 可以省略,默认其他情况就是null
			 max(case when course = '数学' then score end) '数学',
			 max(case when course = '英语' then score end) '英语'
from table_grade
group by user_id  -- 用了聚合函数,那就用group by 去显示

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

  • 如果直接在group by 中加入user_name,是可以的执行的,这样group by的粒度会变细,细粒度的字段可以带粗粒度的字段(此处指select,因为select中只有user_id这一个字段)
  • 如果把user_name加在select子句中,这样在mysql是可以执行的(我这里的mysql8出错了,可能8修改了这个),在orale中是不能执行的。即使mysql中可以执行,那意思就是按照user_id分组,然后带出一个比较细的划分user_id+user_name,而一个user_id可能对应多个user_name,那应该取哪一个呢?mysql会自动取分组中的第一个user_name
  • 不要在group by中加入名字,因为可能会重名
4.1.1.1加入名字的方法1:
select user_id '学生ID',
			 (select max(user_name) from table_grade where user_id = t.user_id) user_name, -- 使用相关子查询(关联子查询)
			 max(case when course = '语文' then score end) '语文',
			 max(case when course = '数学' then score end) '数学',
			 max(case when course = '英语' then score end) '英语'
from table_grade t
group by user_id;
  • 相关子查询中的聚合函数与外面的聚合函数是由区别的,外面的聚合函数是同时按照所有的分组去求最大值的,相关子查询中的聚合函数是外层传入一个值,在内层进行一次查询。
  • 平时的左关联右关联可能会产生笛卡尔积,但是关联子查询是不会产生笛卡尔积的,因为它每次外查询传入一个值,所以永远都是外对内是一对多,不会造成笛卡尔积
  • 上面的相关子查询中加max()是为了防止出错,因为表中同一个ID对应多个名字,如果不加max()的话,就会报错:Subquery returns more than 1 row,即子查询返回了多行。所以此处需要加一个函数进行处理,至于决定加哪一个函数,根据需求决定,这后面讲
  • 加入名字还有一种写法就是select … from in ——> 用in也最好是in(1,2) 这种小的组合,如果在in里面嵌套select查询,这种不太好理解,层数太多了

请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/708373.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

kafka入门,数据去重(九)

数据传递语义 至少一次:ACK级别设置为-1分区副本大于等于2ISR里应答的最小副本数量大于等于2 最多一次:ACK级别设置为0 总结: At Least Once:可以保证数据不丢失,但是不能保证数据不重复 At Most Once:可以…

智慧园区运营管理平台解决方案

智慧园区运营管理平台是当今现代城市发展中的一项重要工具。随着城市人口不断增长,对城市基础设施和服务的需求也不断增加。为了有效管理和优化园区内的各项运营活动,智慧园区运营管理平台应运而生。 智慧园区运营管理平台是基于现代信息技术和互联网技术…

10W+前端面试题面试资料八股文

点击下方链接获取全部内容文档题目及其答案: 10W前端面试题&面试资料&八股文题目及其答案 https://m.tb.cn/h.5a7v237?tkQeVPdsoKwr4 CZ3457 部分题目如下: 1. call丶apply丶bind区别及源码实现(手写) 不同点: call…

HTML 编辑器的介绍及推荐

HTML 编辑器 HTML 编辑器是用于编写 HTML 的工具,使用 HTML 编辑器时以编辑主题,索引,自定义窗口,选择添加搜索页。 使用 Notepad 或 TextEdit 来编写 HTML 下列是三种专门用于编辑 HTML 的 HTML 编辑器: Adobe Dream…

ChatGPT实战:高考志愿填报

近期,随着各地陆续发布高考成绩,高考志愿填报市场随之升温,“高报师”再次成为“香饽饽”。填报志愿对中学生来说太难,在一个懵懂的年纪做这样一个决策,份量是比较重的。当普通人没很多的信息做参考的时候,…

【测试效率提升技巧】xmind测试用例转换为excel工具使用手册

【测试效率提升技巧】xmind测试用例转换为excel工具使用手册 一、前置环境配置二、执行Xmind2testcase的转换方法1.在控制台输入xmind2testcase [path/xmind文件路径] [-csv] [-xml] [-json],例:xmind2testcase /root/homin/XX测试点.xmind -csv ##在当前…

HBase(14):HBase架构

1 系统架构 1.1 Client 客户端,例如:发出HBase操作的请求。例如:之前我们编写的Java API代码、以及HBase shell,都是CLient 1.2 Master Server 在HBase的Web UI中,可以查看到Master的位置。 监控RegionServer处理RegionServer故障转移处理元数据的变更处理region的分配或…

【Python 随练】学用 circle 函数画圆形。

题目: 画图,学用circle函数画圆形。 简介: 在本篇博客中,我们将介绍如何使用Python的绘图库来画圆形。我们将使用circle函数来绘制圆形,并提供一个完整的代码示例来演示其用法。 绘制圆形: 要绘制圆形…

使用Megascans,Blender和Substance 3D画家创建渔人旅馆(p1)

今天瑞云渲染小编给大家带来一篇Polina Tarakanova分享的Fishermans Inn项目背后的工作流程,展示了如何完成水分效果,并解释了照明的设置方式。 介绍 你好! 我叫Polina Tarakanova,今年30岁,是一名来自莫斯科的初级环境艺术家。从…

ISE软件基本使用

ISE软件基本使用 基本设置 关联notepad的操作:选择notepad的exe文件路径,并且加 { } 符号,并在结尾加$1。ISE可以设置程序运行的速度等级,该速度等级会影响程序从外部SPI Flash启动的启动速度。JTAG 接口的作用是将编译好的程 序…

pikache靶场通关——CSRF攻击

文章目录 前言使用工具第一关(host:192.168.1.107)、CSRF(get) loginStep.1、以受害者身份登录账号Step.2、以受害者身份点击修改个人信息的按钮Step.3、以黑客身份使用burp进行抓包(查看对面修改格式)Step4、以黑客身…

文件打包解包的方法

文件打包 前言 在很多情况下,软件需要隐藏一些图片,防止用户对其更改,替换。例如腾讯QQ里面的资源图片,哪怕你用Everything去搜索也搜索不到,那是因为腾讯QQ对这些资源图片进行了打包,当软件运行的时候解…

在SpringBoot中的Jackson使用笔记

在SpringBoot中的Jackson使用笔记 常用的java转json,json反序列化为java等方法,这里定义成一个工具类来用jackson package cn.ath.knowwikibackend.util;import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.core.Jso…

VRP基础操作

目录 一、华为VRP 1.1、VRP介绍 1.2、设备管理接口 1.3、Console口登录 1.4、参数配置 二、华为VRP命令行基础 2.1、真机设备初始化启动 2.2、命令行视图 2.3、命令行功能 2.4、命令行在线帮助 2.5、配置系统时钟 2.6、配置标题消息 2.7、命令等级 2.8、用户界面…

Apikit 自学日记:使用全局变量传递参数

全局变量可以在测试过程中动态取值以及赋值,比如:使用登录接口获取token,将token值赋值给自定义全局变量 global_token ,然后在另一个需要使用该token的接口中,使用{{global_token}}或者代码来引用该全局变量&#xff…

基于深度学习的高精度水下目标检测识别系统(PyTorch+Pyside6+YOLOv5模型)

摘要:基于深度学习的高精度水下目标(鱼(fish)、水母(jellyfish)、企鹅(penguin)、海鹦(puffin)、鲨鱼(shark)、海星(starf…

<Windows>《UltraEdit 编辑器之正则表达式(高级查找与替换)》

《UltraEdit 编辑器之正则表达式(高级查找与替换)》 1 查找和替换时开启正则表达式2 正则表达式关键字3 常用操作3.1 替换空行3.2 替换行尾空格3.3 替换行首空格3.4 替换数字0-93.5 替换空格前内容3.5 替换空行或仅含有空格TAB键的行3.6 末尾加分号 4 其…

PostgreSQL入门教程

目录 一、PostgreSQL安装 1、下载 2、安装 二、PostgreSQL操作 1、数据库操作 2、表操作 3、数据操作 一、PostgreSQL安装 本章节以windows系统安装为例,讲解PostgreSQL 15.0的安装过程。 1、下载 访问PostgreSQL官方网站,下载对应的安装包&am…

phpstudy搭建网站,通过快解析端口映射外网访问

phpstudy是一款集成了apache、mysql、php、ftp等web平台的环境搭建工具,可以让用户轻松搭建测试和开发环境,且不必有过多的配置设置工作。使用phpstudy可以快速搭建出一个本地环境的网站,方便进行调试和开发工作。当然也可以快速搭建部署个人…

Antlr4 语法解析器(下)

Antlr4 的两种AST遍历方式:Visitor方式 和 Listener方式。 Antlr4规则文法: 注释:和Java的注释完全一致,也可参考C的注释,只是增加了JavaDoc类型的注释;标志符:参考Java或者C的标志符命名规范,针对Lexer 部分的 Token 名的定义,采用全大写字母的形式,对于parser rule…