杂技-在 SQL 中实现“数组遍历”

问题

session_id hour
1 1
1 2
1 3
1 5
1 6
1 8

对于每一个连续的小时块,求每个块的结束时间。

如上事例数据可以分为 [1, 3], [5, 6], [8] 三块,每个块的结束时间分别是 3, 6, 8

实现 1

这个问题与 https://leetcode.cn/problems/merge-intervals/ 合并区间问题类似。

可以通过对数组一次遍历解决。自然我们可以通过 UDF 实现这个遍历。然后将 group by 后的 hour 列穿入其中。得到类似下面的 SQL

SELECT
    session_id,
    group_hour_get_max(hour)
FROM T
GROUP BY session_id

实现 2

这是在工作中看到的实现。不通过 group by 而是直接遍历每行,通过窗口函数 lag/lead 来获取前后元素。SQL 如下

SELECT
    session_id,
    id
FROM T
QUALIFY
    LEAD(id) OVER (PARTITION BY sid ORDER BY id) - id > 1
    -- or next_id is null

逻辑上:我们如果下一行目标列,跟本行的目标列的差大于阈值,我们就留下这一行。对于 [1, 2, 3] 1 和 2 与下一行的差都为1,所以被过滤掉只剩下 3

其他问题

我们可能想对还未结束的块特殊处理。根据如何判断块的结束有两种实现方式

  1. 下一个块的出现(差超过阈值)代表本块的结束 -> 那我们应该总放弃掉最后一个块
  2. 有空缺即代表结束 -> 如果最后一个块的最大值 < 源数据的最大值,说明有空缺的

总结

实现2用 SQL 的方式模拟了数组的遍历,个人认为是一个非常没必要的复杂度。但是避免了 UDF 也减少了一些维护成本。是一个可以思考的逻辑。

从性能上讲,由于窗口函数的存在,两种实现都需要 shuffle 。

从可读性上讲,实现1逻辑更符合直觉。

从扩展性上讲,实现2的缺点在于没法随着遍历维护状态,所有的状态都必须跟行绑定。如果需要包含之前所有元素的状态,比如之前的最小值,那需要窗口穿入之前所有数据,增加了增加了时间复杂度。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,589评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,615评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,933评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,976评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,999评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,775评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,474评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,359评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,854评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,007评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,146评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,826评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,484评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,029评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,153评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,420评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,107评论 2 356