表: student
+-------------+---------+ | Column Name | Type | +-------------+---------+ | name | varchar | | continent | varchar | +-------------+---------+ 该表可能包含重复的行。 该表的每一行表示学生的名字和他们来自的大陆。
一所学校有来自亚洲、欧洲和美洲的学生。
编写解决方案实现对大洲(continent)列的 透视表 操作,使得每个学生按照姓名的字母顺序依次排列在对应的大洲下面。输出的标题应依次为美洲(America)、亚洲(Asia)和欧洲(Europe)。
测试用例的生成保证来自美国的学生人数不少于亚洲或欧洲的学生人数。
返回结果格式如下所示。
示例 1:
输入: Student table: +--------+-----------+ | name | continent | +--------+-----------+ | Jane | America | | Pascal | Europe | | Xi | Asia | | Jack | America | +--------+-----------+ 输出: +---------+------+--------+ | America | Asia | Europe | +---------+------+--------+ | Jack | Xi | Pascal | | Jane | null | null | +---------+------+--------+
进阶:如果不能确定哪个大洲的学生数最多,你可以写出一个查询去生成上述学生报告吗?
思路:
1、每一列对应一个 continent(America, Asia, Europe)
2、每一行显示该 continent 的学生名字
3、不统计数量,只是把名字按行对齐显示
4、换句话说,你是想把 按 continent 分类的名字列表“旋转”成列。
5、首先用row_number对地区分组,name排序,然后列转行,用pivot,max函数为pivot需要使用聚合函数。因为本题只需要美洲、亚洲、欧洲,所以加个子查询。
select
America,Asia,Europe
from (
select
name,continent,
row_number() over (partition by continent order by name) rn
from student t1
) t
pivot(max(t.name) for continent in ('America' as America,'Asia' as Asia,'Europe' as Europe) )
order by rn;
进阶代码:
select
*
from (
select
name,continent,
row_number() over (partition by continent order by name) rn
from student t1
) t
pivot(max(t.name) for continent in ('America' as America,'Asia' as Asia,'Europe' as Europe) )
order by rn;
with t as (
select
name,
continent,
row_number() over (partition by continent order by name) as rn
from student
)
select *
from t
pivot (
max(name) for continent in ('america' as america, 'asia' as asia, 'europe' as europe)
)
order by rn;
660

被折叠的 条评论
为什么被折叠?



