PostgreSQL unnest,带有 where 子句的 int4range
PostgreSQL unnest, int4range with where clause
我有一个名为 mytable
:
的数据table
╔════╤══════════════════════════════╤══════════╗
║ id │ segments │ duration ║
╠════╪══════════════════════════════╪══════════╣
║ 1 │ {"[1,4)","[6,13)","[15,19)"} │ 14 ║
╟────┼──────────────────────────────┼──────────╢
║ 2 │ {"[3,16)","[19,22)"} │ 16 ║
╚════╧══════════════════════════════╧══════════╝
segments
是以秒为单位的时间间隔数组。
duration
是 segments
中时间间隔的总和,以秒为单位。
例如id
=1,segments
中的三个间隔分别为3、7、4秒。他们在 duration
.
中总共用了 14 秒
我想从此 table 中仅提取满足两个条件的行:
- 没有个人
segments
不少于10秒
- 有一个
duration
至少 10 秒
查询应该只 return id
=1 因为它的每个 segments
都不到 10 秒并且它的 duration
至少是 10 秒。
查询不应 return id
=2 因为其中一个 segments
的长度为 13 秒。它的 duration
至少是 10 秒,但它不符合第一个条件 segments
.
取消横向连接中的数组嵌套,并按 id
计算分组总和。使用布尔聚合 bool_and()
消除小于 10 秒的片段。
select id, segments, sum(elem.upper- elem.lower) as duration
from my_table
cross join unnest(segments) elem
group by id
having bool_and(elem.upper- elem.lower < 10)
and sum(elem.upper- elem.lower) >= 10
您可以进行横向连接:
select t.*
from mytable t
inner join lateral (
select bool_and(seg.upper - seg.lower < 10) to_keep
from unnest(t.segments) seg
) x on x.to_keep
where t.duration >+ 10
子查询拆嵌数组,使用bool_or()
保证所有间隔小于10秒;连接条件消除了不需要的行。
id | segments | duration
-: | :--------------------------- | -------:
1 | {"[1,4)","[6,13)","[15,19)"} | 14
我有一个名为 mytable
:
╔════╤══════════════════════════════╤══════════╗
║ id │ segments │ duration ║
╠════╪══════════════════════════════╪══════════╣
║ 1 │ {"[1,4)","[6,13)","[15,19)"} │ 14 ║
╟────┼──────────────────────────────┼──────────╢
║ 2 │ {"[3,16)","[19,22)"} │ 16 ║
╚════╧══════════════════════════════╧══════════╝
segments
是以秒为单位的时间间隔数组。
duration
是 segments
中时间间隔的总和,以秒为单位。
例如id
=1,segments
中的三个间隔分别为3、7、4秒。他们在 duration
.
我想从此 table 中仅提取满足两个条件的行:
- 没有个人
segments
不少于10秒 - 有一个
duration
至少 10 秒
查询应该只 return id
=1 因为它的每个 segments
都不到 10 秒并且它的 duration
至少是 10 秒。
查询不应 return id
=2 因为其中一个 segments
的长度为 13 秒。它的 duration
至少是 10 秒,但它不符合第一个条件 segments
.
取消横向连接中的数组嵌套,并按 id
计算分组总和。使用布尔聚合 bool_and()
消除小于 10 秒的片段。
select id, segments, sum(elem.upper- elem.lower) as duration
from my_table
cross join unnest(segments) elem
group by id
having bool_and(elem.upper- elem.lower < 10)
and sum(elem.upper- elem.lower) >= 10
您可以进行横向连接:
select t.*
from mytable t
inner join lateral (
select bool_and(seg.upper - seg.lower < 10) to_keep
from unnest(t.segments) seg
) x on x.to_keep
where t.duration >+ 10
子查询拆嵌数组,使用bool_or()
保证所有间隔小于10秒;连接条件消除了不需要的行。
id | segments | duration -: | :--------------------------- | -------: 1 | {"[1,4)","[6,13)","[15,19)"} | 14