SQL168 统计作答次数

发布于:2025-08-07 ⋅ 阅读:(11) ⋅ 点赞:(0)

描述

有一个试卷作答记录表exam_record,请从中统计出总作答次数total_pv、试卷已完成作答数complete_pv、已完成的试卷数complete_exam_cnt。

示例数据 exam_record表(uid用户ID, exam_id试卷ID, start_time开始作答时间, submit_time交卷时间, score得分):

示例输出:

解释:表示截止当前,有11次试卷作答记录,已完成的作答次数为7次(中途退出的为未完成状态,其交卷时间和份数为NULL),已完成的试卷有9001和9002两份。

select
    count(exam_id) as total_pv,
    count(submit_time) as complete_pv,
    count(
        distinct if(submit_time is not null, exam_id, null)
    ) as complete_exam_cnt
from
    exam_record

重点解析:COUNT(DISTINCT IF(...)) 用法

让我们深入讲解这个复杂的表达式:

COUNT(DISTINCT IF(submit_time IS NOT NULL, exam_id, NULL)) AS complete_exam_cnt

🎯 最终目的

统计有多少种不同的试卷被成功完成过

🔍 逐步拆解

第一步:理解 IF 函数

IF(submit_time IS NOT NULL, exam_id, NULL)

这是一个条件判断函数,相当于Excel中的IF函数:

条件 结果
如果 submit_time 不为空 返回 exam_id
如果 submit_time 为空 返回 NULL

💡 简单说:只保留那些"已完成考试"的记录,未完成的标记为NULL

第二步:DISTINCT 去重

DISTINCT IF(...)
  • 只保留唯一的、非NULL的值
  • 相同的 exam_id 只算一次
  • 所有的 NULL 值被忽略

第三步:COUNT 计数

COUNT(...)

统计去重后非NULL值的数量。

📊 实际执行过程

假设原始数据:

exam_id submit_time
101 2023-01-01 10:00
101 2023-01-01 11:00
102 NULL
103 2023-01-02 09:00
103 2023-01-02 10:00
103 2023-01-02 11:00

执行步骤:

  1. 应用IF函数

    101  (因为submit_time不为空)
    101  (因为submit_time不为空)  
    NULL (因为submit_time为空)
    103  (因为submit_time不为空)
    103  (因为submit_time不为空)
    103  (因为submit_time不为空)
  2. DISTINCT去重

    101
    103
    NULL  (NULL被忽略)
  3. COUNT计数

    • 非NULL的唯一值有2个:101和103
    • 结果:2

💡 为什么这样设计?

这种写法巧妙地解决了三个问题:

  1. 过滤未完成的考试(通过IF判断)
  2. 去重(相同试卷ID只算一次)
  3. 排除NULL值(未完成的记录不计入)

网站公告

今日签到

点亮在社区的每一天
去签到