最强、最全面、最频繁考的 SQL 面试题汇总(含答案)

您所在的位置:网站首页 sql优化面试题目及答案解析 最强、最全面、最频繁考的 SQL 面试题汇总(含答案)

最强、最全面、最频繁考的 SQL 面试题汇总(含答案)

2024-07-16 17:43| 来源: 网络整理| 查看: 265

年前,技术群组织了一场数据类的技术&面试讨论会,邀请了一些大厂朋友、23年参加社招和校招的同学来分享:新人如何入门数据和算法岗,面经/面试题经验分享、大厂在算法场景的落地项目及经验分享等热门话题。

结合讨论内容,今天我总结一下面试中最频繁被考的 SQL 面试题,喜欢几点收藏、关注、点赞。文章篇幅有限,完整版,可以文末找我们获取。

本文目录

一、行列转换 二、排名中取他值 三、累计求值 四、窗口大小控制 五、产生连续数值 六、数据扩充与收缩 七、合并与拆分 八、模拟循环操作 九、不使用distinct或group by去重 十、容器–反转内容 十一、多容器–成对提取数据 十二、多容器–转多行 十三、抽象分组–断点排序 十四、业务逻辑的分类与抽象–时效 十五、时间序列–进度及剩余 十六、时间序列–构造日期 十七、时间序列–构造累积日期 十八、时间序列–构造连续日期 十九、时间序列–取多个字段最新的值 二十、时间序列–补全数据 二十一、时间序列–取最新完成状态的前一个状态 二十二、非等值连接–范围匹配 二十三、非等值连接–最近匹配 二十四、N指标–累计去重

一、行列转换

描述:表中记录了各年份各部门的平均绩效考核成绩。 表名:t1 表结构:

a -- 年份 b -- 部门 c -- 绩效得分

表内容:

a b c 2014 B 9 2015 A 8 2014 A 10 2015 B 7 问题一:多行转多列

问题描述:将上述表内容转为如下输出结果所示:

a col_A col_B 2014 10 9 2015 8 7

参考答案:

select a, max(case when b="A" then c end) col_A, max(case when b="B" then c end) col_B from t1 group by a; 问题二:如何将结果转成源表?(多列转多行)

问题描述:将问题一的结果转成源表,问题一结果表名为t1_2。

参考答案:

select a, b, c from ( select a,"A" as b,col_a as c from t1_2 union all select a,"B" as b,col_b as c from t1_2 )tmp; 问题三:同一部门会有多个绩效,求多行转多列结果

问题描述:2014年公司组织架构调整,导致部门出现多个绩效,业务及人员不同,无法合并算绩效,源表内容如下:

2014 B 9 2015 A 8 2014 A 10 2015 B 7 2014 B 6

输出结果如下所示:

a col_A col_B 2014 10 6,9 2015 8 7

参考答案:

select a, max(case when b="A" then c end) col_A, max(case when b="B" then c end) col_B from ( select a, b, concat_ws(",",collect_set(cast(c as string))) as c from t1 group by a,b )tmp group by a; 二、排名中取他值

表名:t2 表字段及内容:

a b c 2014 A 3 2014 B 1 2014 C 2 2015 A 4 2015 D 3 问题一:按a分组取b字段最小时对应的c字段

输出结果如下所示:

a min_c 2014 3 2015 4

参考答案:

select a, c as min_c from ( select a, b, c, row_number() over(partition by a order by b) as rn from t2 )a where rn = 1; 问题二:按a分组取b字段排第二时对应的c字段

输出结果如下所示:

a second_c 2014 1 2015 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 )a where rn = 2; 问题三:按a分组取b字段最小和最大时对应的c字段

输出结果如下所示:

a min_c max_c 2014 3 2 2015 4 3

参考答案:

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 )a where asc_rn = 1 or desc_rn = 1 group by a; 问题四:按a分组取b字段第二小和第二大时对应的c字段

输出结果如下所示:

a min_c max_c 2014 1 1 2015 3 4

参考答案:

select ret.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字段最小、最大排首位

输出结果如下所示:

a min_c max_c 2014 3,1 2,1 2015 4,3 3,4

参考答案:

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


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3