Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

37 学生地理信息报告 #46

Open
astak16 opened this issue Feb 7, 2022 · 0 comments
Open

37 学生地理信息报告 #46

astak16 opened this issue Feb 7, 2022 · 0 comments
Labels

Comments

@astak16
Copy link
Owner

astak16 commented Feb 7, 2022

题目

写一个查询语句实现对大洲( continent )列的   透视表 操作,使得每个学生按照姓名的字母顺序依次排列在对应的大洲下面。输出的标题应依次为美洲( America )、亚洲( Asia )和欧洲( Europe )。

create table student (
	name varchar(50),
	continent varchar(7)
);

insert into student (name, continent) values
('Jane', 'America'),
('Pascal', 'Europe'),
('Xi', 'Asia'),
('Jack', 'America');

SQL:方法一

select America, Asia, Europe from (
	select
		name as America,
		row_number() over(order by name) as rn
	from student where continent = 'America'
) temp1 left join (
	select
		name as Europe,
		row_number() over(order by name) as rn
	from student where continent = 'Europe'
) temp2 on temp1.rn = temp2.rn left join (
	select
		name as Asia,
		row_number() over(order by name) as rn
	from student where continent = 'Asia'
) temp3 on temp1.rn = temp3.rn;

解析

continent 实现透视操作,就是说把 continent 的每一行变成列,再合并重复的列。

要实现透视操作, continent 每个值按照 AmericaEuropeAsia 进行分类并排序。

排序可以使用 row_number()

AmericaEuropeAsia 值作为临时表 temp1temp2temp3 ,使用左连依次将这三个表连接,连接条件是各表的 rn

SQL:方法二

select
	America, Asia, Europe
from (select @america:=0, @europe:=0, @asia:=0) as init, (
	select
		name as America,
		@america:= @america + 1 as america_id
	from student where continent = 'America' order by name
) t1 left join (
	select
		name as Europe,
		@europe:= @europe + 1 as europe_id
	from student where continent = 'Europe' order by name
) t2 on america_id = europe_id left join (
	select
		name as Asia,
		@asia:= @asia + 1 as asia_id
	from student where continent = 'Asia' order by name
) t3 on america_id = asia_id;

解析

方法二和方法一是一样的思路,这里的排序用的是变量。

Tips

方法一和方法二都有一个问题:需要知道哪个大洲的人数最多,人数多的表作为基准表,别的表与它相连,也就是说表连接的方式是从大到小。

SQL:方法三

select
	max(case continent when 'America' then name else null end) America,
	max(case continent when 'Asia' then name else null end) Aisa,
	max(case continent when 'Europe' then name else null end) Europe
from (
	select
		*,
		row_number() over(partition by continent order by name) as rn
	from student
) temp group by rn;

解析

方法三解决了需要先知道哪个大洲人数最多的问题。

使用 row_number() 按照 continent 分组并排序,序号为 rn ,作为临时表 temp

查询临时表 temp 按照 rn 分组

每一列使用 case ... when ... then ... end 查询出 AmericaAsiaEurope ,因为要使用到 group by ,所以需要使用到聚合函数, maxmin 都可以。

@astak16 astak16 added the 困难 label Feb 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant