MySQL:与dense_rank()over()的group by和partition的差异输出?

Posted

技术标签:

【中文标题】MySQL:与dense_rank()over()的group by和partition的差异输出?【英文标题】:MySQL: Difference outputs from group by and partition by with dense_rank() over()? 【发布时间】:2020-08-18 20:15:42 【问题描述】:

我在 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 Output

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

【问题讨论】:

您要解决的问题是什么?我无法访问 leetcode 链接,因为它需要创建一个帐户。您需要解释问题是找到最大值。 的含义,并显示您想要的样本数据结果。 @Emma 感谢您的回复!但是如果有多个最大值,您的答案将不起作用。 @GMB 感谢您的回复!我只是澄清我的问题。很抱歉造成混乱。 【参考方案1】:

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

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

【讨论】:

感谢您的回复!但我的主要困惑是为什么方法 2 的输出与方法 1 不同?我还是不明白。

以上是关于MySQL:与dense_rank()over()的group by和partition的差异输出?的主要内容,如果未能解决你的问题,请参考以下文章

mysql窗口函数rank() over、dense_rank() over、row_number() over 使用心得

MySql中row_number()rank()dense_rank() 的区别

MySQL 从 DENSE_RANK() 结果更新相同的表字段

DENSE_RANK() OVER (Order by UniqueIdentifer) 问题

oracle的row_number()over rank()over和dense_rank()over这三种分析函数(转)

Oracle - SELECT DENSE_RANK OVER(ORDER BY、SUM、OVER 和 PARTITION BY)