一文搞懂连续问题

本文涉及的产品
云原生大数据计算服务 MaxCompute,5000CU*H 100GB 3个月
云原生大数据计算服务MaxCompute,500CU*H 100GB 3个月
简介: **SQL面试中,连续问题涉及窗口函数如row_number()、lag()、sum()over(order by)等,旨在测试综合能力。关键在于特定分组下,为连续内容分配相同分组ID。解题通常分为判断连续条件和后续处理两步。双排序差值法和累积求和法是常见策略。举例来说,连续登录天数、连续点击次数等题目,会在得到分组ID后用聚合函数统计分析。题目难度逐步升级,涉及销售额增长、时间间隔、涨幅条件等,要求灵活应用并处理复杂逻辑。**

一、连续问题简述

我们写过各式各样的连续,今天我们做一个总结。

连续问题考察范围可能涉及到:开窗函数,lag函数,row_number(),sum()over(order by) 等各种函数,以及相关数据处理技巧等,无论选取那种方法,连续问题都是相对较为复杂,考察综合能力的一类问题。

我们先思考一下什么是连续,如果给出一份数据,我们怎么才能"直接"查询出连续的内容呢?

  • 是给出上一数据的日期?
  • 还是给出与上一数据的差值?
  • 还是给出每个是否与上一数据是否连续的标志字段?

都不是,而是特定分组下,将连续内容赋值相同的分组ID;

再次强调,是在特定分组下,将连续的内容赋值相同的分组ID;

解释:

特定分组:指的是连续的主体,例如判断用户是否连续登录,则这个特定分组是每个用户;
连续分组赋值相同的分组ID,是指添加一列为group_id, 连续的行分配相同的的ID值,该ID在不同的连续组之间不同。

面试题目是不能这样出的,因为这样描述起来太过复杂,很难描述清楚,并且描述完成之后基本就给出了答案,所以题目往往是要求求取连续之后的聚合信息,例如:查询最大连续天数、合并连续的数据、查询连续超过N的用户等等。

二、解题思路

我们以得到分组ID为界,将整个求解过程分为两部分,第一部分为判断连续条件,第二部分为连续之后的处理逻辑。基本上所有的题目都是在这两部分上增加逻辑来提升面试题目的复杂度。

计算连续分组赋值相同的分组ID

判断连续条件,有两种处理思路:1.双排序差值法;2.累积求和法;

1.双排序差值法

双排序差值法是指对一列连续数据得到排序1,对符合条件数据进行排序的到排序2,两列排序差值作为分组ID的方法.如果实际数据连续,则差值不变,如果间断则差值变化,从而保证每个连续段有唯一组id.

我们以腾讯大数据面试SQL-连续登陆超过N天的用户 为例,查询分组ID的逻辑SQL如下

select user_id,
       login_date,
       datediff(from_unixtime(unix_timestamp(login_date, 'yyyyMMdd'), 'yyyy-MM-dd'), '2022-01-01') as date_diff,
       row_number() over (partition by user_id order by login_date asc)                            as row_num,
       row_number() over (partition by user_id order by login_date asc) -
       datediff(from_unixtime(unix_timestamp(login_date, 'yyyyMMdd'), 'yyyy-MM-dd'), '2022-01-01') as diff
from t_login_log;

执行结果

+----------+-------------+------------+----------+-------+
| user_id  | login_date  | date_diff  | row_num  | diff  |
+----------+-------------+------------+----------+-------+
| 0001     | 20220101    | 0          | 1        | 1     |
| 0001     | 20220102    | 1          | 2        | 1     |
| 0001     | 20220103    | 2          | 3        | 1     |
| 0001     | 20220104    | 3          | 4        | 1     |
| 0001     | 20220105    | 4          | 5        | 1     |
| 0001     | 20220107    | 6          | 6        | 0     |
| 0001     | 20220108    | 7          | 7        | 0     |
| 0001     | 20220109    | 8          | 8        | 0     |
| 0002     | 20220101    | 0          | 1        | 1     |
| 0002     | 20220102    | 1          | 2        | 1     |
| 0002     | 20220103    | 2          | 3        | 1     |
| 0002     | 20220107    | 6          | 4        | -2    |
| 0002     | 20220108    | 7          | 5        | -2    |
| 0003     | 20220107    | 6          | 1        | -5    |
| 0003     | 20220108    | 7          | 2        | -5    |
| 0003     | 20220109    | 8          | 3        | -5    |
+----------+-------------+------------+----------+-------+

先计算出当前日期与一个固定日期(具体是什么日期无所谓,只是以一个固定日期为锚点)的差得到排序值1(date_diff),然后使用row_number()函数根据用户分组,按照登陆日期进行排序得到排序值2(row_num),然后用两个排序值做差,谁减去谁都无所谓,差值正负无关。可以看出只要连续登陆的数据,diff值就是相同的。如果出现间断,则差值变化。diff即我们要的连续分组赋值相同的分组ID

2.累积求和法

累积求和法,利用sum()over(order by) 函数特性,累加求和到当前行,如果值为0则累加和不变的特性。巧妙的将连续记录标记为0,不连续的数据标记为1,从而得到连续分组赋值相同的分组ID的目的。

常见大数据面试SQL-连续点击三次用户为例,求取连续分组赋值相同的分组ID过程为:

select user_id,
       click_time,
       is_same_user,
       sum(is_same_user) over (order by click_time asc) as sum_order
from (select user_id,
             click_time,
             case
                 when lag(user_id) over (order by click_time asc) is null then 0
                 when user_id = lag(user_id) over (order by click_time asc) then 0
                 else 1 end as is_same_user
      from t_click_log) t

执行结果

+----------+-------------+---------------+------------+
| user_id  | click_time  | is_same_user  | sum_order  |
+----------+-------------+---------------+------------+
| 1        | 1736337600  | 0             | 0          |
| 2        | 1736337670  | 1             | 1          |
| 1        | 1736337710  | 1             | 2          |
| 1        | 1736337715  | 0             | 2          |
| 1        | 1736337750  | 0             | 2          |
| 2        | 1736337760  | 1             | 3          |
| 3        | 1736337820  | 1             | 4          |
| 3        | 1736337840  | 0             | 4          |
| 3        | 1736337850  | 0             | 4          |
| 3        | 1736337910  | 0             | 4          |
| 4        | 1736337915  | 1             | 5          |
+----------+-------------+---------------+------------+

题目是分析用户是否连续点击,使用lag函数得到上一行用户id与当前行用户id进行比较,如果相同则赋值为0,如果不相同则赋值为1,得到is_same_user列,然后对其使用sum(is_same_user)over(order by click_time),得到累积求和的结果。因为是同一个用户,则累积和不变,如果不同累积和+1,于是得到了连续分组赋值相同的分组ID sum_order 字段。

统计分析得到最终结果

在得到分组ID之后,根据分组ID与特定分组的列,进行分组,即可得到每个连续的段。然后使用聚合函数统计连续行数(连续天数)或者max或者min得到最大最小值等。或者对结果再次筛选得到对应的用户等。或者对数据进行拼接聚合等,总之后续添加逻辑即可。

三、详细题目拆解

普通连续问题

1. 拼多多大数据面试SQL-求连续段的最后一个数及每个连续段的个数

该题目是在得到连续分组ID 之后,增加了聚合逻辑的考察,考察max(),count()函数;

2. 腾讯大数据面试SQL-连续登陆超过N天的用户

该题目是在得到连续分组ID 之后,增加了聚合逻辑的考察,count()统计连续登陆天数,然后对统计结果进行筛选;

3. 常见大数据面试SQL-连续点击三次用户

该题目是在得到连续分组ID 之后,增加了聚合逻辑的考察,count()统计连续登陆天数,然后对统计结果进行筛选;

中等难度连续问题

1.常见大数据面试SQL-销售额连续3天增长的商户

该题目先是对连续条件增加要求,要求销售额增长。然后是在得到连续分组ID 之后,count()统计连续天数,并对统计结果进行筛选。

2. 百度大数据面试SQL-合并用户浏览行为

该题目先是对连续条件增加要求,要求与上一行数据时间差小于60S,得到连续分组ID 之后将数据进行合并处理。

3.腾讯大数据面试SQL-连续5天涨幅超过5%的股票

该题目是在限制要求每天涨幅的大于5%之后,得到连续分组ID,然后要求连续天数大于5天。

4. 京东大数据面试SQL-合并数据

该题目属于在得到分组ID之后,增加了数据进行拼接聚合的的要求。

高难度连续问题

1. 百度大数据面试SQL-连续签到领金币

该题目对连续条件判断上增加了难度,按月分组,在得到连续分组ID之后,计算出连续天数,还需要对天数进行重置,之后又对不同天数得到金币数量进行计算。 整体上十分的繁琐复杂。但是依旧是在得到连续分组ID前后增加一些处理逻辑。

2. 常见大数据面试SQL-各用户最长的连续登录天数-可间断

该题目在连续问题上增加难度,先要求去除重复数据,然后需要判断连续,间隔一天也属于连续。在得到连续分组ID之后 需要计算出连续登陆的最早和最晚日期,然后差值计算,还需要考虑到差值与登陆天数差天的细节。

总结

通过以上面试题目可以看出,只要找到连续分组ID,所以的题目都可以迎刃而解。重要的是判断每个条件属于判断连续的逻辑还是连续之后的处理逻辑就好。

相关实践学习
基于MaxCompute的热门话题分析
本实验围绕社交用户发布的文章做了详尽的分析,通过分析能得到用户群体年龄分布,性别分布,地理位置分布,以及热门话题的热度。
SaaS 模式云数据仓库必修课
本课程由阿里云开发者社区和阿里云大数据团队共同出品,是SaaS模式云原生数据仓库领导者MaxCompute核心课程。本课程由阿里云资深产品和技术专家们从概念到方法,从场景到实践,体系化的将阿里巴巴飞天大数据平台10多年的经过验证的方法与实践深入浅出的讲给开发者们。帮助大数据开发者快速了解并掌握SaaS模式的云原生的数据仓库,助力开发者学习了解先进的技术栈,并能在实际业务中敏捷的进行大数据分析,赋能企业业务。 通过本课程可以了解SaaS模式云原生数据仓库领导者MaxCompute核心功能及典型适用场景,可应用MaxCompute实现数仓搭建,快速进行大数据分析。适合大数据工程师、大数据分析师 大量数据需要处理、存储和管理,需要搭建数据仓库?学它! 没有足够人员和经验来运维大数据平台,不想自建IDC买机器,需要免运维的大数据平台?会SQL就等于会大数据?学它! 想知道大数据用得对不对,想用更少的钱得到持续演进的数仓能力?获得极致弹性的计算资源和更好的性能,以及持续保护数据安全的生产环境?学它! 想要获得灵活的分析能力,快速洞察数据规律特征?想要兼得数据湖的灵活性与数据仓库的成长性?学它! 出品人:阿里云大数据产品及研发团队专家 产品 MaxCompute 官网 https://www.aliyun.com/product/odps 
相关文章
|
7月前
|
算法 Java
算法编程(十四):颠倒二进制位
算法编程(十四):颠倒二进制位
68 0
|
算法
带你读《图解算法小抄》二十四、字符串(6)
带你读《图解算法小抄》二十四、字符串(6)
|
自然语言处理 算法
带你读《图解算法小抄》二十四、字符串(1)
带你读《图解算法小抄》二十四、字符串(1)
|
存储 算法 JavaScript
带你读《图解算法小抄》二十、滑动窗口(3)
带你读《图解算法小抄》二十、滑动窗口(3)
|
6月前
|
开发框架 .NET
技术好文共享:面试题:找出数组中只出现一次的2个数(异或的巧妙应用)(出现3次)
技术好文共享:面试题:找出数组中只出现一次的2个数(异或的巧妙应用)(出现3次)
|
7月前
|
算法 Java
算法编程(十五):位1的个数
算法编程(十五):位1的个数
54 0
|
6月前
【LeetCode刷题】滑动窗口思想解决:最大连续1的个数 III、将x减到0的最小操作数
【LeetCode刷题】滑动窗口思想解决:最大连续1的个数 III、将x减到0的最小操作数
|
6月前
|
存储 算法
数据结构学习记录——图应用实例-六度空间(题目描述、算法思路、伪代码及解读、图解)
数据结构学习记录——图应用实例-六度空间(题目描述、算法思路、伪代码及解读、图解)
73 0
|
算法
带你读《图解算法小抄》二十四、字符串(4)
带你读《图解算法小抄》二十四、字符串(4)
|
算法
带你读《图解算法小抄》二十四、字符串(2)
带你读《图解算法小抄》二十四、字符串(2)