SQL实战:04之SQL中的分组问题求解

文章目录

概述

最近刷题时遇到一些比较有意思的题目,乍一遇上时还不知道怎么求解,在灵光一闪时找到了问题的求解答案,感觉还比较有意思。题目虽然不是很难,但是要解答出来还是需要有一点思维的转弯,为了加深记忆,就选取了一道记录下来。

题目:分组问题求解

如下为电商公司用户访问时间数据,某个用户连续的访问记录如果时间间隔小于 60 秒,则分为同一个组.

表logs

字段名 数据类型
id bigint
ts bigint

输入数据如下:

id ts(秒)
1001 17523641234
1001 17523641256
1002 17523641278
1001 17523641334
1002 17523641434
1001 17523641534
1001 17523641544
1002 17523641634
1001 17523641638
1001 17523641654

参考结果:

id ts(秒) group
1001 17523641234 1
1001 17523641256 1
1001 17523641334 2
1001 17523641534 3
1001 17523641544 3
1001 17523641638 4
1001 17523641654 4
1002 17523641278 1
1002 17523641434 2
1002 17523641634 3

题解

第一步:求解差值

因为需要按照id分组,求解每个用户连续访问时间间隔小于60秒,则放在同一组,所以需要使用窗口函数,将上一行的ts移动到下一行,进行差值运算。

需要用到的知识点:

  • PARTITION BY
  • LAG():下移值
SQL 复制代码
WITH temp_001 AS (
    SELECT id
        ,ts
        ,ts - LAG(ts,1,ts) OVER (PARTITION BY id ORDER BY ts ASC) AS ts_diff
    FROM logs
)

输出如下:

id ts ts_diff
1001 17523641234 17523641234
1001 17523641256 22
1001 17523641334 78
1001 17523641534 200
1001 17523641544 10
1001 17523641638 94
1001 17523641654 16
1002 17523641278 17523641278
1002 17523641434 156
1002 17523641634 200

步骤二:窗口分组累加

由上面的中间结果我们已经得出了一个ts的差值ts_diff,按照滑动 窗口顺序遍历窗口中的每一行数据,如果ts_diff的值大于指定的值60,则加1,否则加0。

第一行ts_diff的值大于60,则加1结果是1,然后第二行值为22加0,值还是为1

第二行和第一行的分组id就都是1了,分在了同一组达到了我们想要的效果。

第三行ts_diff的值是78大于60,加1结果为2,组的ID变成了2。

其他的依次如上。

SQL实现:

sql 复制代码
SELECT id
    ,ts
    ,SUM(IF(ts_diff>60,1,0)) OVER(PARTITION BY id  ORDER BY ts ASC) AS group
FROM temp_001

输出结果:

id ts(秒) group
1001 17523641234 1
1001 17523641256 1
1001 17523641334 2
1001 17523641534 3
1001 17523641544 3
1001 17523641638 4
1001 17523641654 4
1002 17523641278 1
1002 17523641434 2
1002 17523641634 3

完整SQL

SQL 复制代码
WITH temp_001 AS (
    SELECT id
        ,ts
        ,ts - LAG(ts,1,ts) OVER (PARTITION BY id ORDER BY ts ASC) AS ts_diff
    FROM logs
)
SELECT id
    ,ts
    ,SUM(IF(ts_diff>60,1,0)) OVER(PARTITION BY id  ORDER BY ts ASC) AS group
FROM temp_001;

总结

这道题考察的知识点就是对窗口的理解和运用,第一步下移并做差值运算一般都可以快速想到,第二步就需要一点点思维的闪光。利用IF做归一话处理并使用滑动窗口求和得到分组的组号。

相关推荐
高梦轩1 小时前
PG数据库
数据库·oracle
云草桑1 小时前
DBA mssql 解决排序规则冲突 QA prod 和开发配置都是一样的服务器排序规则 为啥开发环境的的存储过程需要 加这个COLLATE Chinese_PRC_CI_AS
数据库·dba·mssql
卤炖阑尾炎1 小时前
MySQL 故障排查与生产环境优化实战指南
数据库·mysql
小陈工1 小时前
2026年4月2日技术资讯洞察:数据库融合革命、端侧AI突破与脑机接口产业化
开发语言·前端·数据库·人工智能·python·安全
solihawk1 小时前
分区大表统计信息不准确引发的性能问题
数据库
百结2142 小时前
postgresql日常运用
数据库·postgresql·oracle
前进的李工3 小时前
MySQL大小写规则与存储引擎详解
开发语言·数据库·sql·mysql·存储引擎
CoovallyAIHub3 小时前
Sensors 2026 | 从无人机拍摄到跑道缺陷地图,机场巡检全流程自动化——Zadar机场全跑道验证
数据库·架构·github
炸炸鱼.4 小时前
PostgreSQL 日常维护速查手册
数据库·oracle