LeetCode 1076:GROUP BY与窗口函数SQL写法差异咨询
LeetCode 1076 两段SQL核心差异说明
题目要求是编写SQL返回所有员工数量最多的项目,两段代码的核心差异集中在聚合逻辑、窗口函数分区逻辑两个关键点,正确性完全不同:
第一段代码:逻辑完全错误,无法得到正确结果
对应代码:
SELECT T1.PROJECT_ID FROM ( SELECT P.PROJECT_ID, DENSE_RANK() OVER (partition by PROJECT_ID ORDER BY COUNT(*) DESC) AS CRANK FROM PROJECT AS P ) AS T1 WHERE T1.CRANK = 1;
存在两个致命问题:
- 缺少
GROUP BY聚合步骤:没有先按项目维度分组统计总员工数,直接在项目-员工的原始明细关系表上做计算,COUNT(*)的统计口径从根源上错误。 - 窗口函数分区逻辑错误:
DENSE_RANK()加了PARTITION BY PROJECT_ID,意味着按项目拆成独立的排名分区,每个项目只在自己的分区内参与排名——相当于自己和自己比,不管项目有多少员工,在自己的分区里永远排第1。最终查询会返回原明细表中所有行对应的项目ID,结果完全不符合要求。
第二段代码:逻辑正确,符合题目要求
对应代码:
SELECT T1.PROJECT_ID FROM ( SELECT P.PROJECT_ID, DENSE_RANK() OVER ( ORDER BY COUNT(*) DESC) AS CRANK FROM PROJECT AS P group by PROJECT_ID ) AS T1 WHERE T1.CRANK = 1
逻辑链路完全通顺:
- 首先通过
GROUP BY PROJECT_ID完成前置聚合:每个项目返回一行,COUNT(*)对应该项目的总员工数。 - 其次
DENSE_RANK()没有指定PARTITION BY,意味着所有聚合后的项目放在同一个排名池里,按员工总数倒序排名,所有员工数并列最高的项目排名都会是1,正好覆盖题目要求的「返回所有员工数量最多的项目」的场景,不会漏掉并列第一的结果。
核心差异总结
- 聚合层面:第一段缺失按项目分组的步骤,基于原始明细计算;第二段先按项目分组统计员工数,统计口径正确。
- 窗口排名层面:第一段按项目分区做组内排名,永远返回所有项目;第二段全局排名,只保留员工数最高的项目。
内容的提问来源于stack exchange,提问作者Lucy
相关产品推荐
相关产品推荐

