SQL168 统计作答次数

描述

有一个试卷作答记录表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_idsubmit_time
1012023-01-01 10:00
1012023-01-01 11:00
102NULL
1032023-01-02 09:00
1032023-01-02 10:00
1032023-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值(未完成的记录不计入)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值