SQL之COALESCE()

现有一张题目练习记录表practice_record,示例内容如下:

id uid question_id submit_time score
1 1001 8001 2021-08-02 11:41:01 60
2 1002 8001 2021-09-02 19:30:01 50
3 1002 8001 2021-09-02 19:20:01 70
4 1002 8002 2021-09-02 19:38:01 70
5 1003 8002 2021-08-01 19:38:01 80
SELECT
    coalesce(DATE_FORMAT(submit_time,"%Y%m"),'2021汇总') submit_month,
    COUNT(submit_time) month_q_cnt,
    round(COUNT(submit_time) / MAX(DAY(last_day(submit_time))),3)avg_day_q_cnt
FROM
    practice_record
WHERE
    year(submit_time) = '2021'
GROUP BY
    DATE_FORMAT(submit_time,"%Y%m") WITH ROLLUP;

开始的想法
开始就想着先算出来然后最后一行用union加上

就遇到了个问题:

计算平均

这里开始我的想法就是计算这个月与下个月之间的日期差datediff然后发现没办法用,要求两个都是date类型,怎么把下个月表示出来是个问题,除非两次转换,所以就放弃了

last_day()
然后看到一个神奇的函数就是last_day()返回参数日期的最后一天那再用day不就能获取这个月的天数了嘛

也就是day(last_day(subnit_time))

select
DATE_FORMAT(submit_time,'%Y%m') as submit_month,
count(*) as month_q_cnt,
round(count(*) / day(last_day(submit_time)) ,3) as avg_day_q_cnt
from practice_record
and year(submit_time) = '2021'
group by DATE_FORMAT(submit_time,'%Y%m')
 
union all
 
select
'2021汇总' as submit_month,
count(*) as month_q_cnt,
round(count(*) /31 ,3) as avg_day_q_cnt -- /30 会不通过用例
from practice_record where score is not null
and year(submit_time) = '2021'
 
order by submit_month ;
    
再然后就做好了嘛,就看看题解,发现了这两个东西


SELECT
    coalesce(DATE_FORMAT(submit_time,"%Y%m"),'2021汇总') submit_month,
    COUNT(submit_time) month_q_cnt,
    round(COUNT(submit_time) / MAX(DAY(last_day(submit_time))),3)avg_day_q_cnt
FROM
    practice_record
WHERE
    year(submit_time) = '2021'
GROUP BY
    DATE_FORMAT(submit_time,"%Y%m") WITH ROLLUP;
新知识时间
coalesce
COALESCE是一个函数,coalesce (expression_1, expression_2, ...,expression_n)依次参考各参数表达式,遇到非null值即停止并返回该值。

SQL实例

1
select coalesce(success_cnt, 1) from tableA
当success_cnt 为null值的时候,将返回1,否则将返回success_cnt的真实值。

1
select coalesce(success_cnt,period,1) from tableA
当success_cnt不为null,那么无论period是否为null,都将返回success_cnt的真实值(因为success_cnt是第一个参数),当success_cnt为null,而period不为null的时候,返回period的真实值。只有当success_cnt和period均为null的时候,将返回1。

在这里题解用的是第一种,也就是当submit_time为null的时候返回一个‘2021汇总’加到最后 那最后的均值呢?

with rollup
with在sql语句中定义在group by之后。当需要对数据库数据进行分类统计的时候,往往会用上groupby进行分组。而在groupby后面还可以加入withcube和withrollup等关键字对数据进行汇总。不过这个cube在mysql中并不适用。

使用 WITH ROLLUP,此函数是对聚合函数进行求和,注意 with rollup是对 group by 后的第一个字段,进行分组计算。

题目应该也是想让用这个函数因为题上给的最后平均就是总数/31而不是一年的365 or366

所以使用这个函数刚好可以

请从中统计出2021年每个月里用户的月总刷题数month_q_cnt 和日均刷题数avg_day_q_cnt(按月份升序排序)以及该年的总体情况,示例数据输出如下:

submit_month month_q_cnt avg_day_q_cnt
202108 2 0.065
202109 3 0.100
2021汇总 5 0.161

猜你喜欢

转载自blog.csdn.net/weixin_48272780/article/details/129152695
今日推荐