PostgreSQL:Select 行连续多次大于某个值
PostgreSQL: Select rows greater than a value by a number of consecutive times
我有以下 table:
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
我需要 select 第一行 ch1 大于 100 且连续超过 5 次。
在上面table:
- 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次
- return 来自 select
的行 ID 15
我开始编写代码:
SELECT id, updated_on, ch1, CASE WHEN ch1>100 THEN 1 ELSE 0 END greater FROM table order by updated_on
但我不知道如何从这里继续。
您可以使用 window 函数来解决这个 gaps-and-islands 问题。
您将首先构建值大于 100
且计数为 window 的连续记录组。然后,枚举每组中的行,最后对每组的第5条记录进行过滤。
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
id | updated_on | ch1
-: | :------------------ | ------:
15 | 2020-03-23 08:42:35 | 106.737
我有以下 table:
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
我需要 select 第一行 ch1 大于 100 且连续超过 5 次。 在上面table:
- 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次
- return 来自 select 的行 ID 15
我开始编写代码:
SELECT id, updated_on, ch1, CASE WHEN ch1>100 THEN 1 ELSE 0 END greater FROM table order by updated_on
但我不知道如何从这里继续。
您可以使用 window 函数来解决这个 gaps-and-islands 问题。
您将首先构建值大于 100
且计数为 window 的连续记录组。然后,枚举每组中的行,最后对每组的第5条记录进行过滤。
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
id | updated_on | ch1 -: | :------------------ | ------: 15 | 2020-03-23 08:42:35 | 106.737