【SQL应知应会】行列转换(三)• Oracle版

请添加图片描述

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

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

请添加图片描述

行列转换 • Oracle版

  • oracle的行列转换
  • 前言
  • 1.数据准备
    • 1.1知识点补充
    • 1.2 知识点应用
  • 2.行转列
    • 2.1通用的行转列(Mysql和Oracle都能用) ——> case when
    • 2.2 私有方法的行转列(Oracle用) ——> decode()
    • 2.3 终极方法(Oracle用) ——> 透视表函数pivot()
      • 2.3.1理论
      • 2.3.2 应用
      • 2.3.3美化
  • 3.列转行
    • 3.1`with as`
    • 3.2进行一个列转行的操作(这是通用方法) ——> union
    • 3.3 列转行终极方法(Oracle用) ——> unpivot()
    • 3.4 一个学生一门课有多次成绩的时候
  • 小结

oracle的行列转换

前言

前面的两篇文章【SQL应知应会】行列转换(一)• MySQL版和【SQL应知应会】行列转换(二)• MySQL版详细的讲述了MySQL的行列转换,而今天这篇文章,讲的是Oracle中的行列转换,其中有与MySQL共同的方法,也有Oracle专用的方法,希望对大家在学习上能有所帮助。

1.数据准备

1.1知识点补充

create table table_grade(id int,user_name varchar(20),course varchar(10),score decimal(5,2));

oracle 中没有int,有integer类型,不过兼容 oracle没有double
oracle没有varchar类型,有varchar2,不过使用varchar也可以建
decimal有,但是建进去会变成number,number既支持整数又支持小数,最大可以设置到38位

drop table table_grade purge;

oracle 删除的时候要加purge,因为oracle有回收站机制,不加purge的话会将删除的东西放在回收站中,这样的话,之后还需要进行一个recyclebin的操作

PURGE RECYCLEBIN; -- 清空某一用户的所有表空间下的对象

1.2 知识点应用

create table table_grade (id number(38),user_name varchar(20),course varchar(10),score decimal(5));insert into table_grade values('1','张龙','语文','78');
insert into table_grade values('2','张龙','数学','95');
insert into table_grade values('3','张龙','英语','81');
insert into table_grade values('4','赵虎','语文','97');
insert into table_grade values('5','赵虎','数学','78');
insert into table_grade values('6','赵虎','英语','91');
insert into table_grade values('7','王五','语文','81');
insert into table_grade values('8','王五','数学','55');
insert into table_grade values('9','王五','英语','75');
insert into table_grade values('10','马六','语文','87');
insert into table_grade values('11','马六','数学','65');
insert into table_grade values('12','马六','英语','75');commit; -- 插入数据后,需要进行一个提交

2.行转列

2.1通用的行转列(Mysql和Oracle都能用) ——> case when

select id "学生ID",    -- oracle中单引号被识别为字段里的一个值,所以别名使用双引号 -- 我的猜想:好像加as就可以用单引号了--> 没验证成功(select max(user_name) from table_grade where id = t.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
group by id;

2.2 私有方法的行转列(Oracle用) ——> decode()

select id "学生ID",(select max(user_name) from table_grade where id = t.id) user_name,max(decode(course,'语文',score,'')) "语文",max(decode(course,'数学',score,'')) "数学",max(decode(course,'英语',score,'')) "英语"
from table_grade t
group by id order by 1-- decode(字段或字段的运算,值1,值2,值3)-- 当字段或字段的运算的值等于值1时,该函数返回值2,否则返回值3-- 当然值1,值2,值3也可以是表达式,这个函数使得某些sql语句简单了许多

2.3 终极方法(Oracle用) ——> 透视表函数pivot()

2.3.1理论

select * from table_name
pivot(max(column_name)   -- 行转列后的列的值value,聚合函数是必须要有的for column_name in (value_1,value_2,value_3)) -- 需要行转列的列及其对应的属性1/2/3

2.3.2 应用

select * from table_grade 
pivot(max(score)   -- 此处max()改成min/sum/avg是一样的,因为此时的table_grade表中,一个学生每门课就有一个成绩for course in ('语文' 语文,'数学' 数学,'英语' 英语))  -- 先写值value,因为course是字符串,所以加单引号   后面是别名

2.3.3美化

select user_name,语文,数学,英语 from table_grade 
pivot(max(score)for course in ('语文' 语文,'数学' 数学,'英语' 英语)) 
order by user_name 

3.列转行

3.1with as

  • with as 是oracle特有写法,可以将as中的查询当做一个表来使用
with table_grade_wide 
as (select 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 tgroup by user_name)
  • 然后就可以当做一个表使用了
  select * from table_grade_wide 

3.2进行一个列转行的操作(这是通用方法) ——> union

- select * from (select 姓名,'语文' course,语文 score from table_grade_wideunion  -- 如果此处使用union all 的话,和union是没有区别的,前一句是赋值语文,下一句是赋值数学,二者union不会去重,相当于产生一个course字段分别是语文和数学,所以二者去重是不会消掉数据的select 姓名,'数学' ,数学 from table_grade_wideunionselect 姓名,'英语' ,英语 from table_grade_wide) -- a -- 这里这个虚拟的表就可以当做真实的表来使用了,所以就不需要给它别名了 -- ?为什么可以当做真实的表用了?这是oracle的原因吗-- where score id not null 	 -- 这句如果原来表中有的学生就没有其中一门课的数据,比如王五和马六只有两门课的数据,那就可以通过这句话来解决table_grade_wide表中王五和马六对应的没有的那门课的null;如果表中的学生有课但是成绩是null,那就没有必要使用这句代码,不然就把学生拥有的那门课删掉了,相当于造成了数据丢失order by 姓名 

3.3 列转行终极方法(Oracle用) ——> unpivot()

with table_grade_wide 
as (select 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 tgroup by user_name)
select 姓名 user_name,course,score from table_grade_wide unpivot(score for course in (语文,数学,英语)) 

3.4 一个学生一门课有多次成绩的时候

  • 数据准备
    在这里插入图片描述
  • 代码
# 求一个学生每门课程近三次考试中最高的成绩
SELECT t1.s_id,t1.c_id, MAX(t1.score) AS best_score
FROM (SELECT s_id,c_id, score, ROW_NUMBER() OVER (PARTITION BY s_id,c_id ORDER BY exam_date DESC) AS rnFROM sc
) t1
WHERE t1.rn <= 3
GROUP BY t1.s_id,t1.c_id

小结

好了,Oracle的行列转换到这里就要告一段落了,相信大家通过前两篇文章【SQL应知应会】行列转换(一)• MySQL版和【SQL应知应会】行列转换(二)• MySQL版,应该对MySQL的行列转换有了了解,并且通过今天这篇文章对Oracle的行列转换也进行了学习,应该对MySQL和Oracle的行列转换的相同以及不同之处有所了解,那么数据库的行列转换这一模块我们就告一段落了,接下来还会给大家带来其他方面的知识讲解,希望能对大家有所帮助
请添加图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

免费开源 | 基于SpringBoot的博客系统

介绍 基于springboot后端架构&#xff0c;websocket实现私信&#xff0c;前端采用thymeleafbootstraplayuiRedis 注册使用邮箱验证注册&#xff0c;且验证码存在redis中&#xff0c;所以需要有redis环境 软件架构 springbootwebsocketthymeleafbootstraplayuiRedismysql 8.…

vue项目业务实现,视频监控-文件流,大屏适配方案(v-scale-screen),websocket前端

最近把以前的业务场景及解决方案整理了一下&#xff0c;具体实现的工具如下&#xff1a; 监控-视频文件流>video.js videojs-contrib-hls 大屏适配方案> v-scale-screen websocket>sockjs-client webstomp-client 视频监控-文件流 使用方法 下载video插件&#xf…

Jmeter性能优化方案

最近用jmeter测试并发出现了访问端口异常问题的排查及解决方案做一个归纳&#xff1a; 背景&#xff1a;接口压测异常情况发生率达到了99% 线上情况&#xff1a; 错误情况展示&#xff1a; 原因&#xff1a; Jmeter里的http sample勾选了keep alive&#xff0c;导致会话一直…

系统上线前,SQL脚本的9大坑

前言 系统上线时&#xff0c;非常容易出问题。 即使之前在测试环境&#xff0c;已经执行过SQL脚本了。但是有时候&#xff0c;在系统上线时&#xff0c;在生产环境执行相同的SQL脚本&#xff0c;还是有可能出现一些问题。 有些小公司&#xff0c;SQL脚本是开发自己执行的&am…

第47步 深度学习图像识别:SqueezeNet建模(Pytorch)

基于WIN10的64位系统演示 一、写在前面 &#xff08;1&#xff09;SqueezeNet SqueezeNet是一种轻量级的深度神经网络架构&#xff0c;由Iandola等人在2016年提出。这种模型的最大特点是参数量极少&#xff0c;仅有510千个参数&#xff0c;而且模型大小只有5MB&#xff0c;比…

MobileNeRF在Windows上的配置

MobileNeRF于2023年提出&#xff0c;源码地址&#xff1a;https://github.com/google-research/jax3d/tree/main/jax3d/projects/mobilenerf &#xff0c;论文为&#xff1a;《MobileNeRF: Exploiting the Polygon Rasterization Pipeline for Efficient Neural Field Renderin…

步入JAVA——环境搭建与项目通览

前言 在这篇文章中&#xff0c;荔枝会介绍如何配置Java后端开发环境并借助一个Java web项目简单介绍一下Java的后端开发逻辑。与python的后端开发逻辑是类似的&#xff0c;Java的后端开发其实也是通过一个个类来实现的。对于像荔枝这种小白白来说&#xff0c;入门的第一个练手J…

GitHub快速上手--GitHub高效操作教程

一、前言 如果你正在看我的这篇文章&#xff0c;说明你已经对GitHub有了一些基础的了解&#xff0c;下面我们将详细叙述每一步的操作&#xff0c;以保证你能够快速上手GitHub&#xff0c;完成对代码的管理。 二、创建仓库 登录GitHub账号&#xff0c;点击页面右上角的加号&am…

idea创建web项目没有jsp选项,不识别jsp,没有tomcat选项

如果你的idea的web项目中没有jsp选项 同时也不识别jsp 那么建议你检查一下你的idea是否为社区版 如果是社区版那么没有jsp的问题无法解决&#xff0c;这只是无法识别&#xff0c;但是语句对的可以正常运行 解决这个问题建议换个idea 至于tomcat&#xff0c; 在plugins中搜s…

人工智能与Chat GPT

一本书全面掌握ChatGPT&#xff0c;既有向ChatGPT提问的技巧&#xff0c; 也有构建自己的ChatGPT模型的方法&#xff0c;涵盖开发背景、关联技术、使用方法、应用形式、实用案例等 人工智能是我们这个时代最热门的话题&#xff0c;人们既希望它能代替我们做一些工作&#xff0c…

Azure 中 Linux的时间同步问题

问题概述 Azure环境中&#xff0c;将群集主机放置在不同的可用区。由于网络限制比较严格没有开启外部或内部NTP时间同步&#xff0c;而是考虑用Azure主机的时间同步&#xff0c;但群集会由于时间差异而出现异常告警信息。 问题分析 问题主要是以下原因形成&#xff1a; 自…

Android Glide预加载RecyclerViewPreloader,ViewPreloadSizeProvider,kotlin

Android Glide预加载RecyclerViewPreloader,ViewPreloadSizeProvider&#xff0c;kotlin implementation com.github.bumptech.glide:glide:4.15.1implementation ("com.github.bumptech.glide:recyclerview-integration:4.14.2") {// Excludes the support library …