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

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 【SQL应知应会】行列转换(三)• 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 t
   group by user_name)


然后就可以当做一个表使用了

select * from table_grade_wide


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

- select * from (
    select 姓名,'语文' course,语文 score from table_grade_wide
    union  -- 如果此处使用union all 的话,和union是没有区别的,前一句是赋值语文,下一句是赋值数学,二者union不会去重,相当于产生一个course字段分别是语文和数学,所以二者去重是不会消掉数据的
    select 姓名,'数学' ,数学 from table_grade_wide
    union
    select 姓名,'英语' ,英语 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 t
   group 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 rn
  FROM sc
) t1
WHERE t1.rn <= 3
GROUP BY t1.s_id,t1.c_id

小结

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


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
2月前
|
SQL 监控 Oracle
Oracle SQL性能优化全面指南
在数据库管理领域,Oracle SQL性能优化是确保数据库高效运行和数据查询速度的关键
|
2月前
|
SQL 存储 Oracle
Oracle数据库SQL语句详解与应用指南
在数字化时代,数据库已成为各类企业和组织不可或缺的核心组件。Oracle数据库作为业界领先的数据库管理系统之一,广泛应用于各种业务场景。掌握Oracle数据库的SQL语句是数据库管理员、开发人员及运维人员的基本技能。本文将详细介绍Oracle数据库SQL语句的基本概念、语法、应用及最佳实践。一、Or
81 3
|
2月前
|
SQL Oracle 关系型数据库
Oracle SQL:了解执行计划和性能调优
Oracle SQL:了解执行计划和性能调优
70 1
|
5月前
|
SQL Oracle 关系型数据库
MySQL、SQL Server和Oracle数据库安装部署教程
数据库的安装部署教程因不同的数据库管理系统(DBMS)而异,以下将以MySQL、SQL Server和Oracle为例,分别概述其安装部署的基本步骤。请注意,由于软件版本和操作系统的不同,具体步骤可能会有所变化。
375 3
|
5月前
|
SQL 存储 Oracle
TDengine 3.3.2.0 发布:新增 UDT 及 Oracle、SQL Server 数据接入
**TDengine 3.3.2.0 发布摘要** - 开源与企业版均强化性能,提升WebSocket、stmt模式写入与查询效率,解决死锁,增强列显示。 - taos-explorer支持geometry和varbinary类型。 - 企业版引入UDT,允许自定义数据转换。 - 新增Oracle和SQL Server数据接入。 - 数据同步优化,支持压缩,提升元数据同步速度,错误信息细化,支持表名修改。 - 扩展跨平台支持,包括麒麟、Euler、Anolis OS等。
131 0
|
SQL 移动开发 Oracle
|
2月前
|
存储 Oracle 关系型数据库
Oracle数据库的应用场景有哪些?
【10月更文挑战第15天】Oracle数据库的应用场景有哪些?
192 64
|
11天前
|
存储 Oracle 关系型数据库
数据库数据恢复—ORACLE常见故障的数据恢复方案
Oracle数据库常见故障表现: 1、ORACLE数据库无法启动或无法正常工作。 2、ORACLE ASM存储破坏。 3、ORACLE数据文件丢失。 4、ORACLE数据文件部分损坏。 5、ORACLE DUMP文件损坏。
48 11
|
24天前
|
Oracle 关系型数据库 数据库
Oracle数据恢复—Oracle数据库文件有坏快损坏的数据恢复案例
一台Oracle数据库打开报错,报错信息: “system01.dbf需要更多的恢复来保持一致性,数据库无法打开”。管理员联系我们数据恢复中心寻求帮助,并提供了Oracle_Home目录的所有文件。用户方要求恢复zxfg用户下的数据。 由于数据库没有备份,无法通过备份去恢复数据库。
|
1月前
|
存储 Oracle 关系型数据库
oracle数据恢复—Oracle数据库文件大小变为0kb的数据恢复案例
存储掉盘超过上限,lun无法识别。管理员重组存储的位图信息并导出lun,发现linux操作系统上部署的oracle数据库中有上百个数据文件的大小变为0kb。数据库的大小缩水了80%以上。 取出&并分析oracle数据库的控制文件。重组存储位图信息,重新导出控制文件中记录的数据文件,发现这些文件的大小依然为0kb。

推荐镜像

更多
下一篇
DataWorks