月总刷题数和日均刷题数(sql练习)

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

iduidquestion_idsubmit_timescore
1100180012021-08-02 11:41:0160
2100280012021-09-02 19:30:0150
3100280012021-09-02 19:20:0170
4100280022021-09-02 19:38:0170
5100380022021-08-01 19:38:0180

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

submit_monthmonth_q_cntavg_day_q_cnt
20210820.065
20210930.100
2021汇总50.161

解释:2021年8月共有2次刷题记录,日均刷题数为2/31=0.065(保留3位小数);2021年9月共有3次刷题记录,日均刷题数为3/30=0.100;2021年共有5次刷题记录(年度汇总平均无实际意义,这里我们按照31天来算5/31=0.161)

牛客已经采用最新的Mysql版本,如果您运行结果出现错误:ONLY_FULL_GROUP_BY,意思是:对于GROUP BY聚合操作,如果在SELECT中的列,没有在GROUP BY中出现,那么这个SQL是不合法的,因为列不在GROUP BY从句中,也就是说查出来的列必须在group by后面出现否则就会报错,或者这个字段出现在聚合函数里面。

示例1

输入:

drop table if exists practice_record;
CREATE TABLE  practice_record (
    id int PRIMARY KEY AUTO_INCREMENT COMMENT '自增ID',
    uid int NOT NULL COMMENT '用户ID',
    question_id int NOT NULL COMMENT '题目ID',
    submit_time datetime COMMENT '提交时间',
    score tinyint COMMENT '得分'
)CHARACTER SET utf8 COLLATE utf8_general_ci;

INSERT INTO practice_record(uid,question_id,submit_time,score) VALUES
(1001, 8001, '2021-08-02 11:41:01', 60),
(1002, 8001, '2021-09-02 19:30:01', 50),
(1002, 8001, '2021-09-02 19:20:01', 70),
(1002, 8002, '2021-09-02 19:38:01', 70),
(1003, 8002, '2021-08-01 19:38:01', 80);

输出:

202108|2|0.065
202109|3|0.100
2021汇总|5|0.161

本题考察sql的综合应用。

首先将日期转换为对应格式,这里用到concat字符拼接和if判断。

其次是根据月份获得对应月的总天数,以便后续进行运算,这里用到case when语句,其语法是:

case when 表达式 then ... when 表达式 then ... end as new_name。注意这里的end不能忘记。

另外还用到了union拼接两个结构相同的表。这里注意order by不能在待拼接的表中单独使用,会报错,必须在union后的整张表使用。本题中对整张表使用order by恰好能达成最终的效果。

select
    submit_month,
    count(*) month_q_cnt,
    round(count(*)/all_day,3) avg_day_q_cnt
from
    (select
        concat(year(submit_time),if(length(month(submit_time))=1,concat('0',month(submit_time)),month(submit_time))) submit_month,
        case
            when month(submit_time) in (1,3,5,7,8,10,12) then 31
            when month(submit_time) in (4,6,8,9,11) then 30
            when month(submit_time)=2 then 28
        end
        as all_day
    from
        practice_record
    where
        year(submit_time)='2021') a
group by
    submit_month,all_day

union

select
    (select '2021汇总') submit_month,
    count(*) month_q_cnt,
    round(count(*)/31,3) avg_day_q_cnt
from
    (select
        concat(year(submit_time),if(length(month(submit_time))=1,concat('0',month(submit_time)),month(submit_time))) submit_month,
        case
            when month(submit_time) in (1,3,5,7,8,10,12) then 31
            when month(submit_time) in (4,6,8,9,11) then 30
            when month(submit_time)=2 then 28
        end
        as all_day
    from
        practice_record
    where
        year(submit_time)='2021') a

order by
    submit_month
  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值