• 牛客网之SQL100题(6)--时间、日期


    知识点

    (1)获取系统时间

    1

    2

    3

    4

    5

    6

    7

    8

    #获取当前系统的日期时间

    SELECT NOW(); # 2021-12-22 13:50:58

    #获取当前系统的日期

    SELECT CURDATE(); # 2021-12-22

    #获取当前系统的时间

    SELECT CURTIME(); # 13:53:11

    (2)获取某年某月某日的日期

    1

    2

    4

    7

    year/month函数:year(date)=2021 and month(date)=8

    date_format函数:date_format(date, "%Y-%m")="202108"

    date like '%2021-08%'

    示例:question_practice_detail

    iddevice_idquestion_idresultdate
    12138111wrong2021-05-03
    23214112wrong2021-05-09
    33214113wrong2021-06-15
    46543111right2021-08-13
    52315115right2021-08-13
    62315116right2021-08-14
    72315117wrong2021-08-15
    ……

    28、运营想要计算出2021年8月每天用户练习题目的数量,请取出相应数据。

    1. 方法1
    2. select day(date) as day,
    3. count(question_id) as question_cnt
    4. from question_practice_detail
    5. where month(date)=8 and year(date)=2021
    6. group by date
    7. 方法2
    8. select day(date) as day,
    9. count(question_id) as question_cnt
    10. from question_practice_detail
    11. where date like '%2021-08%'
    12. group by date ----date换成day也可以
    13. 方法3
    14. select day(date) as day,
    15. count(question_id) as question_cnt
    16. from question_practice_detail
    17. where date_format(date, "%Y-%m") like "2021-08"
    18. group by date

    根据示例,你的查询应返回以下结果:

    dayquestion_cnt
    135
    142
    153
    161
    181

    29、现在运营想要查看用户在某天刷题后第二天还会再来刷题的平均概率。请你取出相应数据。

    解题思路:

    次日留存率=去重的数据表中所有条目数目/去重的数据表中符合次日留存的条目数目​

    1. SELECT
    2. COUNT(q2.device_id) / COUNT(q1.device_id) AS avg_ret
    3. FROM
    4. (SELECT DISTINCT device_id, date FROM question_practice_detail)as q1
    5. LEFT JOIN
    6. (SELECT DISTINCT device_id, date FROM question_practice_detail) AS q2
    7. ON q1.device_id = q2.device_id AND q2.date = DATE_ADD(q1.date, interval 1 day)
    8. --具体而言,使用两个子查询,查询出两个去重的数据表,
    9. --并使用条件(q2.date应该是q1.date的后一天)进行筛选,
    10. --如下所示(数据未显示完全,从左至右顺序,列表名为 q1.device_id, q1.date, q2.device_id, q2.date)
    11. --注意,MySQL中 COUNT在对列进行计数时不统计值为 null的条目

    解题思路:

    • 限定条件:第二天再来。

      解法1:表里的数据可以看作是全部第一天来刷题了的,那么我们需要构造出第二天来了的字  段,因此可以考虑用left join把第二天来了的拼起来,限定第二天来了的可以用 date_add(date1, interval 1 day)=date2筛选,并用device_id限定是同一个用户。

      解法2:用lead函数将同一用户连续两天的记录拼接起来。先按用户分组partition by  device_id,再按日期升序排序order by date,再两两拼接(最后一个默认和null拼 接),即lead(date) over (partition by device_id order by date)

      平均概率:

      解法1:可以count(date1)得到左表全部的date记录数作为分母,count(date2)得到右表关联上了的date记录数作为分子,相除即可得到平均概率

      解法2:检查date2和date1的日期差是不是为1,是则为1(次日留存了),否则为0(次日未留存),取avg即可得平均概率。

    1. --方法1:
    2. select count(date2) / count(date1) as avg_ret
    3. from (
    4. select
    5. distinct a.device_id,
    6. a.date as date1,
    7. b.date as date2
    8. from question_practice_detail as a
    9. left join(
    10. select distinct device_id, date
    11. from question_practice_detail
    12. ) as b
    13. on a.device_id = b.device_id
    14. and date_add(a.date, interval 1 day)=b.date
    15. ) as id_last_next_date
    16. --方法2:
    17. select avg(if(datediff(date2, date1)=1, 1, 0)) as avg_ret
    18. from (
    19. select
    20. distinct device_id,
    21. date as date1,
    22. lead(date) over (partition by device_id order by date) as date2
    23. from (
    24. select distinct device_id, date
    25. from question_practice_detail
    26. ) as uniq_id_date
    27. ) as id_last_next_date

    返回以下结果:

    avg_ret
    0.3000

  • 相关阅读:
    opencv之图像翻转、平移、缩放、旋转、仿射学习笔记
    P1074 [NOIP2009 提高组] 靶形数独
    机器学习---支持向量机的初步理解
    Nginx七层负载均衡之动静分离
    git 命令 简单介绍
    【Matplotlib绘制图像大全】(十):Matplotlib使用boxplot()绘制箱线图
    有什么进销存软件,比较适合零售行业日常开单要求及库存记录?
    day21-web开发会话技术03
    FastDFS学习(四)
    云服务器ECS的简介
  • 原文地址:https://blog.csdn.net/weixin_48272780/article/details/127942072