【SQL】滴滴DS数据分析笔试SQL+编程部分
一、计算连续3天登录的用户数
表t_user中有两个字段user_id和login_date,要求求出连续3天登录的用户数。
思路:
本题的重点在于如何体现“连续”。
使用窗口函数row_number(),如果用登陆日期减去对应的行号,若是连续的话,得到的值应该是一致的
SELECT user_id
FROM (
SELECT
user_id,
login_date,
row_number() OVER(PARTITION BY user_id ORDER BY login_date) AS rn,
date_sub(login_date, rn) AS flag_date
FROM t_user
) tmp
GROUP BY tmp.user_id, date_sub(login_date, rn) -- 每个用户每次连续登录的分块
HAVING COUNT(1) >= 3注:上述代码仅求出了连续登录3天以上的所有user_id,并非user_id数。
二、已知频数求中位数
给定表t_numbers,包含两列,number和frequence,求中位数。
思路:
计算每一个数字的上累积(小于等于该数的数字个数)、下累积(大于等于该数的数字个数),然后筛选出上下累积都超过频数一半的数字(剩余一个或两个),然后取平均。
SELECT AVG(tmp.number) AS median
FROM (
SELECT
number,
SUM(frequence) OVER(ORDER BY number ASC) AS up_sum, -- 上累积
SUM(frequence) OVER(ORDER BY number DESC) AS down_sum, -- 下累积
SUM(frequence) OVER()/2 AS half
FROM t_numbers
) tmp
WHERE tmp.up_sum >= tmp.half
AND tmp.down_sum >= tmp.half;需要注意OVER()函数的几点:
某个函数() OVER(partition by 列名 -- 分组
order by 列名 -- 排序
rows between unbounded preceding and unbounded following -- 窗口
)(1)如果同时省略窗口和排序语句,那么窗口默认为between unbounded preceding and unbounded following(即整个组);
(2)如果只省略窗口语句而不省略排序语句,那么窗口默认为between unbounded preceding and current row(即当前组的第一行到当前行);
(3)如果省略分组语句而不省略排序语句,那么窗口默认为between unbounded preceding and current row(即当前组的第一行到当前行);
(4)如果同时省略分组语句和排序语句,那么窗口默认为between unbounded preceding and unbounded following(即整个组)。
总结:
一句话,有排序语句时,窗口默认为between unbounded preceding and current row(即当前组的第一行到当前行)。