SQL:分享两个SQL笔试题

前言

公司招人招了四个多月了,前阵子让我出几个笔试题,这里把题目和答案分享下。

题目一:连续登录问题

user_iddt
a2020-09-01
a2020-09-02
a2020-09-05
a2020-09-07
a2020-09-08
a2020-09-09
a2020-09-10
b2020-09-08
b2020-09-09
c2020-09-05
d2020-09-04
d2020-09-05
d2020-09-06
d2020-09-07

题目描述

上表是一个用户活跃表(表名为user_login),包含用户ID和活跃日期。每行数据代表该用户在当天活跃过。

现根据上表写SQL,求出在9月当中,连续活跃天数超过3天的user_id,以及其最大连续天数。

结果应为
 

a4
d4

思路

本体考察逻辑能力。一般连续指标的问题,都是通过等差序列来求的。本题可根据日期进行排序,获得一个差值为1的等差序列rk,如果日期是连续的,那么连续的这段日期其实也是一个差值为1的等差序列,既然两个等差序列的差值分别相同,则两个等差序列对应的差(dt-rk)应该是一个固定值。

如题中的数据,先根据dt排序,得出rk,再用dt-rk,则可以得出dt-rk这列,如果dt-rk的值相同,则说明相同的这几条数据的dt是连续的。根据dt-rk分组,如果count值大于等于3,则说明连续登录天数大于3天。

user_iddtrkdt-rk
a2020-09-0112020-08-31
a2020-09-0222020-08-31
a2020-09-0532020-09-02
a2020-09-0742020-09-03
a2020-09-0852020-09-03
a2020-09-0962020-09-03
a2020-09-1072020-09-03
b2020-09-0812020-09-07
b2020-09-0922020-09-07
c2020-09-0512020-09-04
d2020-09-0412020-09-03
d2020-09-0522020-09-03
d2020-09-0632020-09-03

 答案

select
user_id,
max(count) as count
(
    select
    user_id,
    count(1) as count
    from
    (
        select 
        user_id,
        date_sub(dt,rk) as dt_group
        from
        (
            select 
            user_id,
            dt,
            row_number() over(partition by user_id order by dt desc) as rn
            from user_login
            )
    )
    group by user_id,dt_group
    having count(1) >= 3
)
group by user_id
;

题目二:结余问题

user_idamountdt
a1002020-09-01
a-502020-09-02
a-252020-09-03
b502020-09-01
b502020-09-02
b-502020-09-03

题目描述

上表是一个用户消费-充值表(user_pay)。包含用户id、当日充值/消费总额、日期三个字段。假设每天只有一行数据(即你不需要考虑当天既有充值也有消费的情况)。用户初始结余为0,请根据上表情况写SQL,求出用户每天的结余。
结果应为:

user_idamountdttotal
a1002020-09-01100
a-502020-09-0250
a-252020-09-0325
b502020-09-0150
b502020-09-02100
b-102020-09-0390

思路

本体相较上一题简单多了,主要就是考察下sql熟练度。解法很多,使用窗口函数lag、lead都可以求。

但我给出的答案是开窗、分区、排序后直接用sum求出答案。主要考察是否了解开窗函数中,sort by和order by作用域区别。

答案

select
user_id,
amount,
dt,
sum(amount) over(partition by user_id order by dt) as total
from user_pay

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值