PostgreSQL:选择连续大于某个值的行

问题描述

我有下表:

id  updated_on           ch1
1   2020-03-23 08:30:25  90.577
2   2020-03-23 08:30:55  99.213
3   2020-03-23 08:31:05  101.426
4   2020-03-23 08:31:15  103.457
5   2020-03-23 08:31:25  103.982
6   2020-03-23 08:31:35  101.742
7   2020-03-23 08:31:45  97.983
8   2020-03-23 08:32:15  90.091
9   2020-03-23 08:41:35  96.985
10  2020-03-23 08:41:45  99.468
11  2020-03-23 08:41:55  101.714
12  2020-03-23 08:42:05  103.66
13  2020-03-23 08:42:15  104.388
14  2020-03-23 08:42:25  105.12
15  2020-03-23 08:42:35  106.737
16  2020-03-23 08:42:45  108.19
17  2020-03-23 08:42:55  109.626
18  2020-03-23 08:43:05  110.91

我需要选择ch1大于100并且连续5次以上的第一行。 在上表中:

  • id 1和2低于100
  • id 3、4、5、6大于100,但不连续5次
  • id 7,8,9,10低于100
  • id 11,12,13,14,15大于100和连续5次
  • 从选择中返回行ID 15

我以以下代码开始代码

SELECT id,updated_on,ch1,CASE WHEN ch1>100 THEN 1 ELSE 0 END greater FROM table order by updated_on

但是我不知道如何从这里继续。

解决方法

您可以使用窗口函数来解决此缺岛问题。

您将从建立具有窗口计数的值大于100的连续记录组开始。然后,枚举每组中的行,最后筛选出每组中的第五条记录。

select id,updated_on,ch1
from (
    select
        t.*,row_number() over(partition by grp order by updated_on) rn
    from (
        select 
            t.*,count(*) filter(where ch1 <= 100) over(
                order by updated_on 
                rows between unbounded preceding and 1 preceding
            ) grp
        from mytable t
    ) t
) t
where ch1 > 100 and rn = 5

Demo on DB Fiddlde

id | updated_on          |     ch1
-: | :------------------ | ------:
15 | 2020-03-23 08:42:35 | 106.737