【问题标题】:How to add conditional partition in a window function with trino or impala?如何在 Trino 或 impala 的窗口函数中添加条件分区?
【发布时间】:2022-01-17 09:34:05
【问题描述】:

例如,我有一个如下数据集:

time action
03:00:00 block
04:00:00 unblock
05:00:00 block
06:00:00 unblock
07:00:00 unblock
08:00:00 block

现在对于每一行,我想在当前行的时间之前获得action 列等于“阻塞”的最后时间。例如,对于time等于“07:00:00”且action等于“unblock”的第五行,它之前的最后一次action等于“block”应该是第三行,预计时间为“05:00:00”。

我的最终预期结果是:

time action last_time
03:00:00 block 03:00:00
04:00:00 unblock 03:00:00
05:00:00 block 05:00:00
06:00:00 unblock 05:00:00
07:00:00 unblock 05:00:00
08:00:00 block 08:00:00

如何使用窗口函数不自行加入得到上述结果?

(p.s.如果不能达到上面的结果,下面的输出也是可以的:

time action last_time
03:00:00 block NULL
04:00:00 unblock 03:00:00
05:00:00 block 03:00:00
06:00:00 unblock 05:00:00
07:00:00 unblock 05:00:00
08:00:00 block 05:00:00

【问题讨论】:

    标签: sql window-functions impala trino


    【解决方案1】:

    一旦我们确定 action = 'block' 应该开始一个新块并且我们识别出这些块 (block_no),我们就可以使用由该 block_no 划分的窗口函数来找到每个块内的最小 time

    如果时间不是单调递增的,我们可以使用FIRST_VALUE窗口函数来代替,如果我们有其他的排序方式,或者只在action = 'block'时使用另一个case表达式来获取时间,这将将其他行保留为 null,这很容易通过 MAX/MIN/etc 忽略。

    但是,鉴于当前数据,我认为我们无法解决这样一个假设,即每个块之间的所有行的时间需要单调增加或至少从块到块增加。

    试试这个:

    The fiddle

    WITH cte1 AS (
             SELECT *, SUM(CASE WHEN action = 'block' THEN 1 END) OVER (ORDER BY time) AS block_no FROM test
         )
    SELECT *, MIN(time) OVER (PARTITION BY block_no) AS block_time FROM cte1
     ORDER BY time
    ;
    

    结果:

    time action block_no block_time
    03:00:00 block 1 03:00:00
    04:00:00 unblock 1 03:00:00
    05:00:00 block 2 05:00:00
    06:00:00 unblock 2 05:00:00
    07:00:00 unblock 2 05:00:00
    08:00:00 block 3 08:00:00

    设置:

    CREATE TABLE test (time varchar(20), action  varchar(20));
    
    INSERT INTO test VALUES
      ('03:00:00', 'block')
    , ('04:00:00', 'unblock')
    , ('05:00:00', 'block')
    , ('06:00:00', 'unblock')
    , ('07:00:00', 'unblock')
    , ('08:00:00', 'block')
    ;
    

    【讨论】:

    • @tqd9563 如果答案可以接受,别忘了accept,如果答案有帮助,别忘了upvote
    • 我已经接受了答案,但由于我缺乏声誉而无法投票..
    猜你喜欢
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-18
    • 1970-01-01
    • 1970-01-01
    • 2021-05-02
    相关资源
    最近更新 更多