You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于LeetCode Q1633中SQL COUNT函数计算异常的技术问询

LeetCode Q1633 分子不随GROUP BY动态变化的原因解析

核心问题

你遇到的问题本质是:用来计算「单场比赛参与用户数」的分子,没有和GROUP BY contest_id的分组逻辑绑定,而是使用了全局统计值,导致所有比赛的分子完全相同,最终百分比计算错误。

常见错误场景与原因

1. 使用无关联的全局子查询当分子

比如你的SQL可能写成这样:

SELECT 
    contest_id,
    ((SELECT COUNT(*) FROM Register) / (SELECT COUNT(*) FROM Users)) * 100 AS percentage
FROM Register
GROUP BY contest_id

这里的(SELECT COUNT(*) FROM Register)是独立子查询,它只会执行一次,计算整个Register表的总记录数——不管外层怎么按contest_id分组,这个值都是固定的,自然不会随分组动态变化。

2. 错误使用非分组聚合函数

如果你的分子直接写了全局聚合(比如没放在分组上下文里的聚合函数),也会出现同样问题。SQL的规则是:外层GROUP BY只会作用于直接写在SELECT列表里、且依赖分组字段的聚合函数,如果聚合逻辑和当前分组无关,就只会输出全局统计结果。

正确写法示例

针对Q1633的需求(计算每场比赛的用户参与率,保留两位小数),正确的SQL应该让分子跟着分组动态统计单场比赛的参与用户数:

SELECT 
    contest_id,
    ROUND(COUNT(DISTINCT user_id) * 100.0 / (SELECT COUNT(user_id) FROM Users), 2) AS percentage
FROM Register
GROUP BY contest_id
ORDER BY percentage DESC, contest_id ASC;
  • COUNT(DISTINCT user_id):跟着GROUP BY contest_id执行,每个分组(单场比赛)都会单独统计自己的有效参与用户数(去重避免重复报名的干扰)。
  • (SELECT COUNT(user_id) FROM Users):全局统计总用户数,作为固定分母。
  • ROUND(..., 2):按题目要求保留两位小数。

关键逻辑梳理

SQL执行GROUP BY时,会先把数据按分组字段拆分成多个独立的数据集,然后对每个数据集单独执行聚合函数。如果你的分子没有绑定到当前分组的数据集,而是调用了全局的统计结果,就无法实现“随分组动态变化”的效果。

内容的提问来源于stack exchange,提问作者Laurent

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 11:02:43