订阅更新

回答率最高的问题:条件计数再相除

SQL 实战 123 题 · 第 23 题 中等 约 2 分钟读完

LeetCode 578 · 条件聚合、比率排序

本文目录
  1. 面试怎么回答
  2. 题意
  3. 表结构
  4. 思路
  5. 参考解法
  6. 易错点

面试怎么回答

按 question_id 分组,用 SUM(action = 'answer') / SUM(action = 'show') 算回答率,降序取第一。我会补上 question_id 作为第二排序键保证结果确定,并留意展示为 0 时比值为 NULL 的情况。

先把这段讲顺;面试官追问时,再展开下面的原理和细节。

详细讲解

题意

问卷日志记录了每个问题被展示(show)、回答(answer)、跳过(skip)的行为。回答率 = 回答次数 / 展示次数,找出回答率最高的问题 ID。

表结构

  • survey_log:id(用户)、action(show / answer / skip)、question_id、answer_id、q_num、timestamp

思路

按问题分组,用条件求和分别数出 answer 和 show 的次数,相除后降序取第一。可以先在子查询里算好两个计数再排序,也可以直接在 ORDER BY 里写比值表达式。

参考解法

写法 1:子查询里先算回答数和展示数

select question_id  survey_log
from (
  select
      question_id,
      sum(if(action = 'answer', 1, 0)) as AnswerCnt,
      sum(if(action = 'show', 1, 0)) as ShowCnt
  from
      survey_log
  group by question_id
) as tbl
order by (AnswerCnt / ShowCnt) desc
limit 1

写法 2:直接在 ORDER BY 里用比值

select question_id  survey_log
from survey_log
group by question_id
order by sum(if(action = 'answer', 1, 0)) / sum(if(action = 'show', 1, 0)) desc
limit 1

易错点

  • 展示次数为 0 时除法得到 NULL,降序时 NULL 的位置因数据库而异(MySQL 里 NULL 排在最后),要心里有数。
  • 回答率相同的多个问题,题目通常要求取 question_id 最小的,可以在排序里补 question_id。
刷题进度保存在当前浏览器