Postgresql Postgres tsrange,按日期和时间筛选

Postgresql Postgres tsrange,按日期和时间筛选,postgresql,Postgresql,我有一个events表,其中有一个名为duration的字段,该字段的类型为tsrange,它捕获类型为timestamp的事件的开始和结束时间。我想要的是能够过滤特定日期范围内的所有事件,然后按时间过滤这些事件。因此,例如,用户应该能够过滤(包括)从12-15-2019到12-17-2019之间发生的所有事件,以及在晚上9点播放的事件。为此,用户提交一个日期范围,过滤该日期范围内的所有事件: WHERE lower(duration)::date <@ '[start, finish]'

我有一个
events
表,其中有一个名为
duration
的字段,该字段的类型为
tsrange
,它捕获类型为
timestamp
的事件的开始和结束时间。我想要的是能够过滤特定日期范围内的所有事件,然后按时间过滤这些事件。因此,例如,用户应该能够过滤(包括)从
12-15-2019
12-17-2019
之间发生的所有事件,以及在晚上9点播放的事件。为此,用户提交一个日期范围,过滤该日期范围内的所有事件:

WHERE lower(duration)::date <@ '[start, finish]'::daterange
用户提交的日期范围为
2019-12-21
2019-12-27
,则事件B将被过滤掉。然后用户提交一个9:00PM(21:00)的时间,在这种情况下,将返回a、C和D

编辑

我能够通过以下方式使其工作:

WHERE duration @> (lower(duration)::date || ' 21:00:00')::timestamp

其中,上面的21:00是用户数据,但似乎有点粗俗

a
tsrange
在晚上9点包含时间戳。当且仅当开始日的晚上9点或第二天的晚上9点是范围的一部分时

你可以用它来写你的条件

例如:

lower(r)::date + TIME '21:00' <@ r OR
(lower(r)::date + 1) + TIME '21:00' <@ r

lower(r)::日期+时间“21:00”从2019-12-21到2019-12-27 21:00的用户输入
表示他对

select generate_series(timestamp '2019-12-21 21:00', '2019-12-27 21:00', '1 day') as t

          t
---------------------
 2019-12-21 21:00:00
 2019-12-22 21:00:00
 2019-12-23 21:00:00
 2019-12-24 21:00:00
 2019-12-25 21:00:00
 2019-12-26 21:00:00
 2019-12-27 21:00:00
(7 rows)
因此,您应该检查
duration
列是否包含以下时间戳之一:

select distinct e.*
from events e
cross join generate_series(timestamp '2019-12-21 21:00', '2019-12-27 21:00', '1 day') as t
where duration @> t

 id |                   duration
----+-----------------------------------------------
 A  | ["2019-12-21 19:00:00","2019-12-22 01:10:00")
 C  | ["2019-12-23 19:00:00","2019-12-23 21:10:00")
 D  | ["2019-12-23 19:00:00","2019-12-24 01:10:00")
(3 rows)

我知道,但如果用户提交9:00,那么我需要将该时间与tsrange的日期和时间进行比较,我不确定如何进行比较。我可以将tsrange转换为just time,但是如果某个时间在晚上8:00开始,第二天凌晨2:00结束,我会检查21:00是否在20:00…01:00范围内,这是无法比较的,因为结束时间小于开始时间。我在问题中添加了更多信息。我在答案中添加了一个示例,我认为现在已经很清楚了。为什么需要OR?如果
r
[2019-12-20 23:00:002019-12-22 09:00:00]
,那么
r
不包含
2019-12-20 21:00:00
,但它包含
2019-12-21:00:00
@a_horse\u,没有名字谢谢我做了更改这是一个漂亮的解决方案,但劳伦兹先回答了,并解决了我的问题。
select distinct e.*
from events e
cross join generate_series(timestamp '2019-12-21 21:00', '2019-12-27 21:00', '1 day') as t
where duration @> t

 id |                   duration
----+-----------------------------------------------
 A  | ["2019-12-21 19:00:00","2019-12-22 01:10:00")
 C  | ["2019-12-23 19:00:00","2019-12-23 21:10:00")
 D  | ["2019-12-23 19:00:00","2019-12-24 01:10:00")
(3 rows)