通过代码

select
    exam_id,
    count(*) - count(score) incomplete_cnt,
    round((count(*) - count(score)) / COUNT(*),3) incomplete_rate
FROM
    exam_record
WHERE
         exam_id IN(
        select
            exam_id
        from
            exam_record
        where
            score is  null
    )
GROUP BY
    exam_id

很简单啊,这里就不说了应该都会啊

问题关键是有未完成状态的试卷的未完成数和未完成率。

怎么判断它有没有

有未完成状态的试卷

这里我首先想到的是in,就是先把有未完成试卷的给检索出来判断in就行,这里还有一种思路

通过代码2(试卷完成量过大可能有bug)

select *
from(
    select
        exam_id,
        count(start_time)-count(score) incomplete_cnt,
        round((count(start_time)-count(score))/count(start_time),3) incomplete_rate
    from
        exam_record
    group by 
        exam_id) t
where 
    incomplete_rate != 0.000

就是啥也不管直接把最后完成率为0的筛出来就行。


但是这个有风险,就是如果试卷被做量很庞大,就有一个试卷一共被做了10w+,但只有一次未完成,那它的未完成率四舍五入也是0,但是它的确有未完成


通过代码3

select 
    exam_id,
    sum(if(score is null, 1, 0))  incomplete_cnt,
    round((count(start_time)-count(score))/count(start_time),3)  incomplete_rate
from 
    exam_record
group by 
    exam_id
having 
    incomplete_cnt >= 1

哎这个思路就相比较前面好,直接对分组后进行筛选

having 
  incomplete_cnt >= 1

还有sum代替count来进行计数也可行,count可能会快一点?

不太清楚,问题是这个判题系统有bug,同样的代码不同时间提交会有不同的耗时表现。


通过代码4

SELECT
  exam_id,
  SUM(IF(score IS NULL, 1,0)) incomplete_cnt,
  ROUND(AVG(IF(score IS NULL, 1,0)), 3) incomplete_rate
FROM 
    exam_record
GROUP BY 
    1
HAVING 
    COUNT(score) != COUNT(*)

avg替代count除法,彳亍!

还有gruop by 1 就是group by select后第一字段名

分组后筛选COUNT(score) != COUNT(*)也彳亍!

速度上表现也挺好,就是不知道是不是机器抽风qaq