订阅更新

SQL 实战 123 题

123 道经典 SQL 面试题逐题讲解:题意、思路、参考解法、易错点和面试时怎么讲,覆盖窗口函数、连续区间、行转列、留存等高频套路。

从第 1 篇开始读

  1. 1 两表关联取人员信息:没有地址的人也不能丢LeetCode 175 · LEFT JOIN、保留主表 简单
  2. 2 第二高的薪水:没有第二名时怎么返回 NULLLeetCode 176 · 去重排序、LIMIT OFFSET、空结果转 NULL 简单
  3. 3 第 N 高的薪水:把排名写进函数里LeetCode 177 · 自定义函数、窗口排名、参数化查询 中等
  4. 4 分数排名:并列之后名次要连续LeetCode 178 · DENSE_RANK、RANK 与 ROW_NUMBER 的区别 中等
  5. 5 连续出现三次的数字:LEAD 看后面两行LeetCode 180 · LEAD/LAG、连续性判断 中等
  6. 6 收入超过经理的员工:表和自己关联LeetCode 181 · 自连接 简单
  7. 7 查找重复的邮箱:GROUP BY + HAVINGLeetCode 182 · 分组计数、HAVING 简单
  8. 8 从没下过单的客户:反连接的三种写法LeetCode 183 · LEFT JOIN + IS NULL、NOT EXISTS、NOT IN 的陷阱 简单
  9. 9 每个部门工资最高的员工:并列第一都要LeetCode 184 · 分组 Top 1、RANK、关联维表 中等
  10. 10 部门工资前三高:前三「档」而不是前三个人LeetCode 185 · 分组 Top N、DENSE_RANK 困难
  11. 11 删除重复邮箱:只保留 Id 最小的一条LeetCode 196 · DELETE 自连接、去重保留规则 简单
  12. 12 比昨天温度高的日期:相邻日期要真的相差一天LeetCode 197 · LAG、日期差、自连接 简单
  13. 13 行程取消率:先排除被封禁用户再算比例LeetCode 262 · 条件聚合、过滤维表、比率计算 困难
  14. 14 玩家首次登录日期:MIN 比窗口函数更省事LeetCode 511 · 分组取最小值、窗口排名 简单
  15. 15 玩家首次登录的设备:要整行就用窗口函数LeetCode 512 · 分组取首行、ROW_NUMBER / RANK 简单
  16. 16 截至每天累计玩了多少局:窗口累计求和LeetCode 534 · 累计求和、SUM OVER、自连接 中等
  17. 17 首日次日留存率:AVG 一个布尔值LeetCode 550 · 次日留存、LEFT JOIN、条件求平均 中等
  18. 18 每个公司的薪水中位数:奇偶数一个公式搞定LeetCode 569 · 中位数、ROW_NUMBER、窗口计数 困难
  19. 19 至少有 5 个直接下属的经理LeetCode 570 · 分组计数、IN 子查询、自连接 中等
  20. 20 按频率表求中位数:用累计频数定位LeetCode 571 · 中位数、累计求和、频率展开 困难
  21. 21 得票最多的候选人:先在投票表里聚合LeetCode 574 · 分组计数、Top 1、先聚合再关联 中等
  22. 22 奖金低于 1000 的员工:没有奖金也算LeetCode 577 · LEFT JOIN、NULL 判断 简单
  23. 23 回答率最高的问题:条件计数再相除LeetCode 578 · 条件聚合、比率排序 中等
  24. 24 员工近三个月累计薪水:ROWS 和 RANGE 的区别LeetCode 579 · 滑动窗口、RANGE 窗口、排除最近一个月 困难
  25. 25 各专业学生人数:没有学生的专业也要列出LeetCode 580 · LEFT JOIN 计数、COUNT(列) 与 COUNT(*)、多字段排序 中等
  26. 26 推荐人不是 2 号的客户:NULL 不等于任何值LeetCode 584 · NULL 与三值逻辑 简单
  27. 27 2016 年的投资:两个「唯一性」条件用窗口计数LeetCode 585 · 窗口计数、多条件过滤 中等
  28. 28 订单最多的客户:并列第一也要考虑LeetCode 586 · 分组计数、Top 1、并列处理 简单
  29. 29 大国家:OR 条件与 UNION 的取舍LeetCode 595 · 多条件过滤、OR 与索引 简单
  30. 30 至少 5 名学生的课程:同一个学生别算两次LeetCode 596 · COUNT DISTINCT、HAVING 简单
  31. 31 好友申请总体通过率:分子分母各自去重LeetCode 597 · 去重计数、除零处理 简单
  32. 32 体育馆人流高峰:连续三天以上人数不少于 100LeetCode 601 · 连续区间、LAG/LEAD、行号差分组 困难
  33. 33 谁的好友最多:把双向关系展开成一列LeetCode 602 · UNION ALL 展开双向关系、分组计数 中等
  34. 34 连续空余座位:相邻的空座才算LeetCode 603 · LAG/LEAD、自连接、连续判断 简单
  35. 35 没卖给 RED 公司的销售员:先找出卖过的,再取反LeetCode 607 · 反连接、多层子查询 简单
  36. 36 判断树节点类型:根、内部节点还是叶子LeetCode 608 · CASE WHEN、NOT IN 与 NULL、自关联 中等
  37. 37 判断三条线段能否组成三角形LeetCode 610 · IF / CASE、条件表达式 简单
  38. 38 平面上两点最近距离:笛卡尔积要减半LeetCode 612 · 自连接、笛卡尔积、减少重复计算 中等
  39. 39 直线上两点最近距离:排序后只比相邻点LeetCode 613 · LEAD、排序后相邻差 简单
  40. 40 二级关注者:既被人关注、又去关注别人的用户LeetCode 614 · 自关联、IN 子查询、去重计数 中等
  41. 41 部门平均工资和公司平均工资比较LeetCode 615 · 多粒度聚合、窗口 AVG、CASE 比较 困难
  42. 42 学生按大洲透视:行转列的标准套路LeetCode 618 · 行转列、ROW_NUMBER、条件聚合 困难
  43. 43 只出现一次的最大数字:没有时返回 NULLLeetCode 619 · HAVING、聚合函数遇到空集 简单
  44. 44 有趣的电影:奇数编号且描述不是 boringLeetCode 620 · 取模、多条件过滤、排序 简单
  45. 45 相邻同学换座位:奇偶编号互换LeetCode 626 · CASE、LAG/LEAD、奇偶判断 中等
  46. 46 一条 UPDATE 交换性别字段LeetCode 627 · UPDATE + CASE、单语句修改 简单
  47. 47 买下了所有产品的客户:关系除法LeetCode 1045 · 关系除法、COUNT DISTINCT 与总数比较 中等
  48. 48 合作至少三次的演员和导演LeetCode 1050 · 多列分组、HAVING 简单
  49. 49 产品销售分析一:取每笔销售的产品名LeetCode 1068 · JOIN 维表 简单
  50. 50 产品销售分析二:每个产品卖了多少件LeetCode 1069 · 分组求和、不必要的关联 简单
  51. 51 产品销售分析三:每个产品第一年的销售LeetCode 1070 · 分组取首行、并列保留 中等
  52. 52 项目员工一:每个项目的平均工作年限LeetCode 1075 · JOIN 后分组平均、ROUND 简单
  53. 53 项目员工二:员工最多的项目(含并列)LeetCode 1076 · 分组计数、并列最大值 简单
  54. 54 项目员工三:每个项目里经验最丰富的人(含并列)LeetCode 1077 · 分组 Top 1、RANK 并列 中等
  55. 55 销售分析一:总销售额最高的销售员(含并列)LeetCode 1082 · 分组求和、聚合结果上开窗 简单
  56. 56 销售分析二:买了 S8 却没买 iPhone 的买家LeetCode 1083 · 条件聚合、「有 A 无 B」 简单
  57. 57 销售分析三:只在 2019 年春季卖过的产品LeetCode 1084 · 「全部满足」判断、MIN/MAX 区间 简单
  58. 58 游戏玩法分析五:按安装日统计次日留存LeetCode 1097 · 安装日、次日留存、分组比率 困难
  59. 59 小众书籍:过去一年卖出不到 10 本LeetCode 1098 · LEFT JOIN 带时间条件、ON 与 WHERE 的区别 中等
  60. 60 每日新用户数:先求首登日再按日统计LeetCode 1107 · 首次行为、分组两次 中等
  61. 61 每个学生的最高成绩:并列取课程号最小的LeetCode 1112 · 分组取首行、多字段排序 中等
  62. 62 昨天每种举报理由的帖子数LeetCode 1113 · 条件过滤、去重计数 简单
  63. 63 垃圾帖移除率的每日平均LeetCode 1132 · 先算日比率再求平均、LEFT JOIN 计数 中等
  64. 64 活跃业务:超过平均值的事件类型不少于两个LeetCode 1126 · 窗口 AVG、和组内平均比较 中等
  65. 65 用户购买平台:没有数据的组合也要显示 0LeetCode 1127 · 补全维度组合、用户级打标签、LEFT JOIN 困难
  66. 66 近 30 天每日活跃用户数LeetCode 1141 · 日期范围、去重计数 简单
  67. 67 近 30 天人均会话数LeetCode 1142 · 比率指标、去重计数、空结果处理 简单
  68. 68 看过自己文章的作者LeetCode 1148 · 同表列比较、DISTINCT 简单
  69. 69 同一天读了至少两篇文章的人LeetCode 1149 · 多列分组、去重计数 中等
  70. 70 市场分析一:每个用户 2019 年的买家订单数LeetCode 1158 · 先聚合再左关联、零值补齐 中等
  71. 71 市场分析二:卖出的第二件商品是不是最喜欢的品牌LeetCode 1159 · 分组取第 N 行、LEFT JOIN、NULL 处理 困难
  72. 72 指定日期的产品价格:缓慢变化维的时点查询LeetCode 1164 · 时点查询、取截止日前最后一条、默认值 中等
  73. 73 即时订单占比:布尔条件求平均LeetCode 1173 · 条件计数、百分比 简单
  74. 74 首单中的即时订单占比LeetCode 1174 · 分组取首行、占比 中等
  75. 75 部门月收入行转列:12 个月变 12 列LeetCode 1179 · 行转列、CASE + 聚合 中等
  76. 76 每月交易一:按月和国家统计全部与已批准LeetCode 1193 · 多指标条件聚合、日期格式化分组 中等
  77. 77 每月交易二:批准和退单放在一起统计LeetCode 1205 · UNION ALL 合并事件、条件聚合、过滤全零行 中等
  78. 78 锦标赛每组优胜者:别依赖子查询里的排序LeetCode 1194 · 双向展开、分组取第一、非确定性写法 困难
  79. 79 最后一个能进电梯的人:累计和不超过上限LeetCode 1204 · 累计求和、取满足条件的最后一行 中等
  80. 80 查询质量和劣质查询占比LeetCode 1211 · 比值的平均、条件占比 简单
  81. 81 球队积分:主客场两种身份都要算LeetCode 1212 · 条件求和、OR 关联、零值保留 中等
  82. 82 系统状态的连续日期段:日期减行号找区间LeetCode 1225 · 连续区间(gaps and islands)、UNION ALL、行号差 困难
  83. 83 每个帖子的评论数:同一张表里的帖子和评论LeetCode 1241 · 自关联、去重计数、零值保留 简单
  84. 84 平均售价:按销售日期匹配当时的价格LeetCode 1251 · 区间关联(日期落在价格有效期内)、加权平均 简单
  85. 85 页面推荐:朋友喜欢、而我还没喜欢的页面LeetCode 1264 · 双向关系、IN / NOT IN、去重 中等
  86. 86 直接或间接向 CEO 汇报的人:固定层级的多次自连接LeetCode 1270 · 多级自连接、层级关系、递归 CTE 中等
  87. 87 学生参加各科考试的次数:先做全组合再计数LeetCode 1280 · CROSS JOIN 补全组合、LEFT JOIN 计数 简单
  88. 88 找出连续区间的起止数字LeetCode 1285 · 连续区间、数字减行号 中等
  89. 89 各国 11 月的天气类型:先平均再分档LeetCode 1294 · 聚合后 CASE 分档、日期范围 简单
  90. 90 每个员工所在团队的人数:窗口计数不用回表LeetCode 1303 · 窗口 COUNT、明细保留 简单
  91. 91 男女队每日累计总分LeetCode 1308 · 分区累计求和 中等
  92. 92 餐馆营业额 7 天滑动平均LeetCode 1321 · 先按天汇总、滑动窗口、ROWS 与 RANGE 中等
  93. 93 广告点击率 CTR:分母为 0 时记为 0LeetCode 1322 · 条件计数、除零处理、多字段排序 简单
  94. 94 2020 年 2 月下单不少于 100 件的产品LeetCode 1327 · 日期过滤、分组求和、HAVING 简单
  95. 95 每次到访的交易次数分布:没人的档位也要显示 0LeetCode 1336 · 频次分布、生成数字序列、LEFT JOIN 补零 困难
  96. 96 电影评分:两个独立查询拼成一列LeetCode 1341 · UNION ALL、各自排序取第一、并列按字典序 中等
  97. 97 院系不存在的学生:找出孤儿记录LeetCode 1350 · 反连接、外键完整性检查 简单
  98. 98 活动参与者:既不是最多也不是最少LeetCode 1355 · 分组计数、双向排名、排除极值 中等
  99. 99 顾客的可信联系人数量:按邮箱判断LeetCode 1364 · 多次 LEFT JOIN、条件计数、看清定义 中等
  100. 100 每个用户最近第二次活动:只有一次就返回那一次LeetCode 1369 · 倒序排名、窗口计数、边界处理 困难
  101. 101 用唯一标识码替换员工 IDLeetCode 1378 · LEFT JOIN、保留主表 简单
  102. 102 按年度拆分销售总额:一个区间跨多年LeetCode 1384 · 区间拆分、和年份表关联、区间重叠计算 困难
  103. 103 股票资本损益:卖出记正、买入记负LeetCode 1393 · 带符号求和、条件聚合 中等
  104. 104 买了 A 和 B 却没买 C 的顾客LeetCode 1398 · 条件聚合、「有且无」组合判断 中等
  105. 105 旅行者里程排行:没出行的也要显示 0LeetCode 1407 · LEFT JOIN 求和、零值、按 ID 分组 简单
  106. 106 每场考试都处于中游的学生LeetCode 1412 · 排除极值、双向排名、反连接 困难
  107. 107 净现值查询:查不到就当 0LeetCode 1421 · 复合键 LEFT JOIN、默认值 中等
  108. 108 会话时长分桶:空的桶也要显示 0LeetCode 1435 · 分桶统计、维度表补零、CASE 简单
  109. 109 计算布尔表达式:变量表关联两次LeetCode 1440 · 同一张表关联多次、CASE 分支 中等
  110. 110 苹果和桔子每天的销量差:不要依赖行的顺序LeetCode 1445 · 条件聚合、带符号求和、窗口函数的确定性 中等
  111. 111 连续登录 5 天的活跃用户:先去重再看间隔LeetCode 1454 · 连续登录、去重、LEAD 看第 N 行 中等
  112. 112 任意两点组成的矩形面积LeetCode 1459 · 自连接、去重配对、排除退化情况 中等
  113. 113 按公司最高工资定税率:边界值要看清LeetCode 1468 · 窗口 MAX、分段 CASE、边界条件 中等
  114. 114 各品类周一到周日的销量:日期转星期再行转列LeetCode 1479 · 星期函数、行转列、零值 困难
  115. 115 按日期汇总卖出的产品:GROUP_CONCAT 拼成一列LeetCode 1485 · 字符串聚合、去重排序拼接 简单
  116. 116 6 月播放过的儿童适宜电影LeetCode 1495 · 多条件过滤、去重 简单
  117. 117 平均通话时长高于全球平均的国家LeetCode 1501 · 双向展开、字符串截取关联、和全局平均比较 中等
  118. 118 6 月和 7 月每月消费都满 100 的顾客LeetCode 1511 · 按月汇总、每月都满足、年份过滤 简单
  119. 119 校验合法邮箱:正则里的点要转义LeetCode 1517 · REGEXP 正则、字符串校验 简单
  120. 120 患有 I 型糖尿病的病人:前缀匹配要卡住单词边界LeetCode 1527 · LIKE 模糊匹配、多值字段 简单
  121. 121 每个顾客最近的三笔订单LeetCode 1532 · 分组 Top N、多字段排序 中等
  122. 122 修正产品名格式后按月统计LeetCode 1543 · 数据清洗、TRIM / LOWER、按清洗后的值分组 简单
  123. 123 每个产品最近一次的订单(含同一天多笔)LeetCode 1549 · 分组取最新、RANK 保留并列、多字段排序 中等