在postgres中按条件增加行号

问题描述

我有一个带有时间戳的 postgres 表,以及 difftime 中当前和上一个(滞后)时间戳之间的舍入小时差

 timestamp               type    difftime
 2013-09-14 14:19:46     JPR03   2 
 2013-09-14 15:11:48     JPR03   1 
 2013-09-14 16:11:49     JPR03   1 
 2013-09-14 17:13:45     JPR03   1 
 2013-09-22 00:08:38     JPR03   175 
 2013-09-22 00:10:11     JPR03   0 
 2013-09-22 01:11:36     JPR03   1 
 2013-09-22 02:16:11     JPR03   1 
 2013-09-22 03:13:16     JPR03   1 
 2013-09-22 04:05:38     JPR03   1 
 2013-09-22 06:10:11     JPR03   2 
 2013-09-22 07:26:43     JPR03   1 
 2013-09-22 08:17:35     JPR03   1 
 2013-09-22 09:16:08     JPR03   1 
 2013-09-22 10:16:08     JPR03   1 
 2013-10-01 06:15:07     JPR03   212 
 2013-10-01 06:15:12     JPR03   0 
 2013-10-02 07:15:15     JPR03   25 
 2013-10-02 08:05:09     JPR03   1 

我的目标是创建一个增量行号序列,当且仅当 difftime 中的值高于某个阈值 x(按时间排序)时增加 1。如果 x = 5,则输出将如下所示:

 timestamp               type    difftime  rownum
 2013-09-14 14:19:46     JPR03   2         0
 2013-09-14 15:11:48     JPR03   1         0
 2013-09-14 16:11:49     JPR03   1         0
 2013-09-14 17:13:45     JPR03   1         0
 2013-09-22 00:08:38     JPR03   175       1
 2013-09-22 00:10:11     JPR03   0         1
 2013-09-22 01:11:36     JPR03   1         1
 2013-09-22 02:16:11     JPR03   1         1
 2013-09-22 03:13:16     JPR03   1         1
 2013-09-22 04:05:38     JPR03   1         1
 2013-09-22 06:10:11     JPR03   2         1
 2013-09-22 07:26:43     JPR03   1         1
 2013-09-22 08:17:35     JPR03   1         1
 2013-09-22 09:16:08     JPR03   1         1
 2013-09-22 10:16:08     JPR03   1         1
 2013-10-01 06:15:07     JPR03   212       2
 2013-10-01 06:15:12     JPR03   0         2
 2013-10-02 07:15:15     JPR03   25        3
 2013-10-02 08:05:09     JPR03   1         3

我熟悉 RANK()DENSE_RANK()ROW_NUMBER()COALESCE() 函数,但这些函数都无法实现按条件递增行号的目标( 0 开头)。关于如何实现这种变量赋值的任何建议,或者这里可以应用哪些函数来根据条件进行分区?

解决方法

demo:db<>fiddle

您可以使用带有条件值的累积 SUM() 函数:如果满足条件,则添加 1,否则添加 0

SELECT
    *,SUM(
        CASE 
            WHEN diff >= 5 THEN 1
            ELSE 0
        END
    ) OVER (ORDER BY ts)
FROM --<your query>
,

在 Postgres 中,我建议使用 filter

select q.*,count(*) filter (where diff > ?) over (order by ts) as rownum
from <your query> q;

? 是您想到的任何值的占位符。