欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SQL:分享两个SQL笔试题

程序员文章站 2022-06-16 13:32:53
前言公司招人招了四个多月了,前阵子让我出几个笔试题,这里把题目和答案分享下。题目一:连续登录问题user_iddta2020-09-01a2020-09-02a2020-09-05a2020-09-07a2020-09-08a2020-09-09a2020-09-10b2020-09-08b2020-09-09c2020-09-05d2...

前言

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

题目一:连续登录问题

user_id dt
a 2020-09-01
a 2020-09-02
a 2020-09-05
a 2020-09-07
a 2020-09-08
a 2020-09-09
a 2020-09-10
b 2020-09-08
b 2020-09-09
c 2020-09-05
d 2020-09-04
d 2020-09-05
d 2020-09-06
d 2020-09-07

题目描述

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

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

结果应为
 

a 4
d 4

思路

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

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

user_id dt rk dt-rk
a 2020-09-01 1 2020-08-31
a 2020-09-02 2 2020-08-31
a 2020-09-05 3 2020-09-02
a 2020-09-07 4 2020-09-03
a 2020-09-08 5 2020-09-03
a 2020-09-09 6 2020-09-03
a 2020-09-10 7 2020-09-03
b 2020-09-08 1 2020-09-07
b 2020-09-09 2 2020-09-07
c 2020-09-05 1 2020-09-04
d 2020-09-04 1 2020-09-03
d 2020-09-05 2 2020-09-03
d 2020-09-06 3 2020-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_id amount dt
a 100 2020-09-01
a -50 2020-09-02
a -25 2020-09-03
b 50 2020-09-01
b 50 2020-09-02
b -50 2020-09-03

题目描述

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

user_id amount dt total
a 100 2020-09-01 100
a -50 2020-09-02 50
a -25 2020-09-03 25
b 50 2020-09-01 50
b 50 2020-09-02 100
b -10 2020-09-03 90

思路

本体相较上一题简单多了,主要就是考察下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

 

本文地址:https://blog.csdn.net/x950913/article/details/108981263

相关标签: 杂谈