牛客网之SQL非技术快速入门(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

id device_id question_id result date
1 2138 111 wrong 2021-05-03
2 3214 112 wrong 2021-05-09
3 3214 113 wrong 2021-06-15
4 6543 111 right 2021-08-13
5 2315 115 right 2021-08-13
6 2315 116 right 2021-08-14
7 2315 117 wrong 2021-08-15
……

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

方法1:
select day(date) as day,
       count(question_id) as question_cnt
from question_practice_detail
where month(date)=8 and year(date)=2021
group by date

方法2:
select day(date) as day,
       count(question_id) as question_cnt
from question_practice_detail
where date like '%2021-08%'
group by date      ----date换成day也可以


方法3:
select day(date) as day,
       count(question_id) as question_cnt
from question_practice_detail
where date_format(date, "%Y-%m") like "2021-08"
group by date

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

day question_cnt
13 5
14 2
15 3
16 1
18 1

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

解题思路:

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

SELECT
    COUNT(q2.device_id) / COUNT(q1.device_id) AS avg_ret
FROM
    (SELECT DISTINCT device_id, date FROM question_practice_detail)as q1
LEFT JOIN
    (SELECT DISTINCT device_id, date FROM question_practice_detail) AS q2
ON q1.device_id = q2.device_id AND q2.date = DATE_ADD(q1.date, interval 1 day)

--具体而言,使用两个子查询,查询出两个去重的数据表,
--并使用条件(q2.date应该是q1.date的后一天)进行筛选,
--如下所示(数据未显示完全,从左至右顺序,列表名为 q1.device_id, q1.date, q2.device_id, q2.date)

--注意,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:
select count(date2) / count(date1) as avg_ret
from (
    select
        distinct a.device_id,
        a.date as date1,
        b.date as date2
    from question_practice_detail as a
    left join(
        select distinct device_id, date
        from question_practice_detail
    ) as b
    on a.device_id = b.device_id
        and date_add(a.date, interval 1 day)=b.date
) as id_last_next_date


--方法2:
select avg(if(datediff(date2, date1)=1, 1, 0)) as avg_ret
from (
    select
        distinct device_id,
        date as date1,
        lead(date) over (partition by device_id order by date) as date2
    from (
        select distinct device_id, date
        from question_practice_detail
    ) as uniq_id_date
) as id_last_next_date

返回以下结果:

avg_ret
0.3000

猜你喜欢

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