[SQL should know and know] Row and Column Conversion (3) • Oracle Edition

Please add a picture description

Welcome to the blog of a programmer who loves books but never loses . This blog is dedicated to sharing knowledge and learning and communicating with more people

This article is included in the column of SQL should know and meet . This column is mainly used to record some learning about databases. There are basic and advanced, including MySQL and Oracle.

Please add a picture description

oracle row and column conversion

foreword

The previous two articles [SQL should know and know] row and column conversion (1) • MySQL version and [SQL should know and know] row and column conversion (2) • MySQL version describe the row and column conversion of MySQL in detail, and today's article , it talks about row-column conversion in Oracle. There are common methods with MySQL, and there are also Oracle-specific methods. I hope it will be helpful to everyone in learning.

1. Data preparation

1.1 Supplementary Knowledge Points

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

There is no int in oracle, but there is an integer type, but it is compatible with oracle. There is no double. Oracle does not have a
varchar type. There is varchar2, but you can also use varchar to build
decimal, but it will become a number when built. Number supports both integers and decimals. The maximum can be set to 38 bits

drop table table_grade purge;

When oracle is deleted, purge is required, because oracle has a recycle bin mechanism. If you do not add purge, the deleted things will be placed in the recycle bin. In this case, a recyclebin operation is required later

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

1.2 Application of Knowledge Points

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. Row to column

2.1 Universal row-to-column conversion (both Mysql and Oracle can be used) ——> 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 Row-to-column conversion of private method (for 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 Ultimate method (for Oracle) ——> Pivot table function pivot()

2.3.1 Theory

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 Application

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

2.3.3 Beautification

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

3. Column to row

3.1with as

  • with asIt is a unique writing method of oracle, and the query in as can be used as a table
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)
  • Then it can be used as a table
  select * from table_grade_wide 

3.2 Perform a column transfer operation (this is a general method) ——> 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 The ultimate method of column transfer (for 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 When a student has multiple grades for one course

  • data preparation
    insert image description here
  • the code
# 求一个学生每门课程近三次考试中最高的成绩
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

summary

Well, Oracle's row and column conversion is coming to an end here. I believe you have read the first two articles [SQL should know and understand] row and column conversion (1) • MySQL version and [SQL should know and should know] row and column conversion (2) • For the MySQL version , you should have an understanding of MySQL’s row-column conversion, and through today’s article, you should also learn about Oracle’s row-column conversion. You should have an understanding of the similarities and differences between MySQL and Oracle’s row-column conversion. We have come to an end with the rank and column conversion module. Next, we will bring you other knowledge explanations. I hope it can be helpful to you.
Please add a picture description

Guess you like

Origin blog.csdn.net/qq_40332045/article/details/131575369