首页 > 解决方案 > MySQL:与dense_rank()over()的group by和partition的差异输出?

问题描述

我在 Leetcode 上做一个 MySQL 问题。(链接:https ://leetcode.com/problems/get-highest-answer-rate-question/ )问题是找到最大值。我使用order by + limit 1来得到答案。但是如果有多个最大值呢?限制 1只会返回 1 个答案。

我尝试使用dense_rank() 来解决这个问题,但是当我使用partition by 和group by 时,我发现输出是不同的。

Input: {"headers": {"survey_log": ["id", "action", "question_id", "answer_id", "q_num", "timestamp"]},"rows": {"survey_log": [[5, "show", 285, null, 1, 123], [5, "answer", 285, 124124, 1, 124], [5, "show", 369, null, 2, 125], [5, "skip", 369, null, 2, 126]]}}

输入图像

如果我的代码是:

# Method 1
select question_id, 
dense_rank() over (order by count(case when action = 'answer' then 1 end)/
                            count(case when action = 'show' then 1 end) desc) as num
from survey_log
group by question_id

然后我得到输出:

Output: {"headers": ["question_id", "num"], "values": [[285, 1], [369, 2]]}

但是,当我尝试使用 partition by 来实现相同的效果时,输出不是我想要的:

# Method 2
select question_id, 
dense_rank() over (partition by question_id 
                   order by count(case when action = 'answer' then 1 end)/
                            count(case when action = 'show' then 1 end) desc) as num
from survey_log
Output: {"headers": ["question_id", "num"], "values": [[285, 1]]}

我不知道为什么这里的输出不同。谁能解释一下?提前致谢!!


更新:对不起,我没有清楚地说明这个问题。问题是“编写一个 sql 查询来识别具有最高回答率的问题”。

“最高答题率的意思是:同一题中答题数占节目数的比例。”

至于上面的输入,第285题的回答率为1/1,而第369题的回答率为0/1,所以输出285。那么输出应该是:285 输出

我的困惑是为什么方法 2 的输出与方法 1 不同?谢谢!!

标签: mysqlsqlgroup-bycountwindow-functions

解决方案


我将从计算每个问题的回答率的查询开始。根据您的问题陈述,应该是:

select
    question_id,
    sum(action = 'answer') / nullif(sum(action = 'show'), 0) answer_rate
from survey_log
group by question_id

您可以使用该信息对问题进行排名。您希望针对所有其他组对每个问题进行排名,因此窗口函数不应包含partition子句:

select
    question_id,
    rank() over(order by sum(action = 'answer') / nullif(sum(action = 'show'), 0) desc) rn
from survey_log
group by question_id
order by rn

推荐阅读