排名中取他值问题

表名:t2
表字段及内容:
排名中取他值问题_第1张图片

问题一:按 a 分组取 b 字段最小时对应的 c 字段

输出结果如下所示

排名中取他值问题_第2张图片 

select a,c as min_c 
from ( select a,b,c,row_number() over(partition by a order by b) as rn
 from t2 ) a1
where rn = 1;

问题二:按 a 分组取 b 字段排第二时对应的 c 字段 

输出结果如下所示

排名中取他值问题_第3张图片

select a,c as second_c 
from ( select a,b,c,row_number() over(partition by a order by b) as rn 
from t2 ) a1
where rn = 2;

 问题三:按 a 分组取 b 字段最小和最大时对应的 c 字段

输出结果如下所示

排名中取他值问题_第4张图片

select a,min(if(asc_rn = 1, c, null)) as min_c, 
         max(if(desc_rn = 1, c, null)) as max_c 
from (select a,b,c,row_number() over(partition by a order by b) as asc_rn, 
                   row_number() over(partition by a order by b desc) as desc_rn 
from t2 )a1
where asc_rn = 1 or desc_rn = 1
 group by a;

 问题四:按 a 分组取 b 字段第二小和第二大时对应的 c 字段

输出结果如下所示
排名中取他值问题_第5张图片

 

selectret.a ,max(case when ret.rn_min = 2 then ret.c else null end) as min_c ,
             max(case when ret.rn_max = 2 then ret.c else null end) as max_c 
from (select*,row_number() over(partition by t2.a order by t2.b) as rn_min ,
row_number() over(partition by t2.a order by t2.b desc) as rn_max 
from t2 ) as ret 
where ret.rn_min = 2 or ret.rn_max = 2
 group by ret.a;
问题五:按 a 分组取 b 字段前两小和前两大时对应的 c 字段
注意:需保持 b 字段最小、最大排首位
输出结果如下所示
排名中取他值问题_第6张图片
思路:遇到某一列中需要拼接的情况
==>开窗函数+concat_ws(',',collect_list(c))的配合使用
select tmp1.a as a, min_c, max_c 
from ( select a,concat_ws(',', collect_list(c)) as min_c 
from(select a,b,c,row_number() over(partition by a order by b) as asc_rn 
from t2 )a where asc_rn <= 2 
group by a )tmp1 
join ( select a,concat_ws(',', collect_list(c)) as max_c 
from(select a,b,c,row_number() over(partition by a order by b desc) as desc_rn
from t2 )a1 
where desc_rn <= 2 group by a )tmp2
 on tmp1.a = tmp2.a;

你可能感兴趣的:(经典SQL题,sql,经典SQL题)