SQL查询求助:如何获取游乐设施最大游客数及对应RideID
解决游乐设施游客数统计的SQL问题
嘿,刚接触SQL的话踩这种坑很正常,我来帮你理清楚问题所在,然后给出正确的解决方案~
原查询的问题
你的原语句有两个核心问题:
- 缺少
GROUP BY RideID:你需要按每个游乐设施分组,才能统计每个设施的游客数量,否则数据库不知道要对哪些行聚合计算。 - 聚合函数嵌套错误:
MAX(COUNT(DISTINCT GuestID))这种写法不成立,因为聚合函数(比如COUNT)不能直接嵌套在另一个聚合函数(比如MAX)里,除非通过子查询或CTE来实现。
解决方案
我们分两种场景来处理,分别对应“只需要一个最受欢迎设施”和“返回所有并列第一的设施”的需求。
场景1:只返回一个最受欢迎的设施
如果只需要获取游客数最多的某一个设施(即使有并列也只取其一),可以先分组统计每个设施的游客数,再按游客数降序排序后取第一条:
MySQL/PostgreSQL版本
SELECT RideID, COUNT(DISTINCT GuestID) AS total_guests FROM GUEST_RIDES WHERE RideDate BETWEEN '2016-01-01' AND '2018-12-31' GROUP BY RideID ORDER BY total_guests DESC LIMIT 1;
SQL Server版本
SELECT TOP 1 RideID, COUNT(DISTINCT GuestID) AS total_guests FROM GUEST_RIDES WHERE RideDate BETWEEN '2016-01-01' AND '2018-12-31' GROUP BY RideID ORDER BY total_guests DESC;
场景2:返回所有并列第一的设施
如果存在多个设施游客数相同且都是最大值,想要全部返回,可以用**窗口函数RANK()**来实现:
WITH RideGuestCounts AS ( SELECT RideID, COUNT(DISTINCT GuestID) AS total_guests, -- 按游客数降序排名,并列的设施会得到相同的排名 RANK() OVER (ORDER BY COUNT(DISTINCT GuestID) DESC) AS ride_rank FROM GUEST_RIDES WHERE RideDate BETWEEN '2016-01-01' AND '2018-12-31' GROUP BY RideID ) SELECT RideID, total_guests FROM RideGuestCounts WHERE ride_rank = 1;
这里的CTE(公共表表达式)先统计每个设施的游客数并排名,之后筛选出排名为1的所有设施,就能得到所有并列最受欢迎的游乐设施。
关键知识点
COUNT(DISTINCT GuestID):确保统计的是不同游客的数量,而不是总乘坐次数(如果要统计乘坐次数,去掉DISTINCT即可)。GROUP BY RideID:必须按游乐设施ID分组,才能对每个设施单独计算游客数。- 窗口函数
RANK():适合处理排名类需求,能保留并列结果,比单纯取TOP更灵活。
内容的提问来源于stack exchange,提问作者jeffrey pernia
相关产品推荐
相关产品推荐

