PostgreSQL:选择连续多次大于一个值的行

Posted

技术标签:

【中文标题】PostgreSQL:选择连续多次大于一个值的行【英文标题】:PostgreSQL: Select rows greater than a value by a number of consecutive times 【发布时间】:2020-09-09 23:33:59 【问题描述】:

我有下表:

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 次 从选择返回第 15 行

我开始编写代码:

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

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

【问题讨论】:

【参考方案1】:

您可以使用窗口函数来解决这个差距和孤岛问题。

您将首先构建具有大于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

编号 |更新了 | ch1 -: | :----------------- | ------: 15 | 2020-03-23 08:42:35 | 106.737

【讨论】:

以上是关于PostgreSQL:选择连续多次大于一个值的行的主要内容,如果未能解决你的问题,请参考以下文章

只需要从列表中选择至少存在一个值的行

PostgreSQL,删除具有重新编号列值的行

PostgreSQL 查询包含特定键值的 json 对象中的行

PostgreSQL 查询列上具有最小空值的行

有序 postgresql 数组中大于 x 的最小值的位置(优化)

如何将多次包含相同值的行导入另一个工作表