【问题标题】:Postgres search available time slots with generate_seriesPostgres 使用 generate_series 搜索可用时隙
【发布时间】:2018-10-17 01:30:37
【问题描述】:

我的 postgres 数据库中有一个表,其中有一列日期。我想搜索缺少哪些日期 - 例如:

date
2016-11-09 18:30:00
2016-11-09 19:00:00
2016-11-09 20:15:00
2016-11-09 22:20:00
2016-11-09 23:00:00

这里,|2016-11-09 21:00:00| 不见了。如果我的表在两个插槽(间隔为 1 小时的插槽)之间有一个条目,则在对生成的系列进行排序后,我需要将其删除。

我想使用generate_series 进行查询,返回丢失的日期。这可能吗?

我用来生成系列的示例查询。

    SELECT t
    FROM generate_series(
       TIMESTAMP WITH TIME ZONE '2016-11-09 18:00:00',
       TIMESTAMP WITH TIME ZONE '2016-11-09 23:00:00',
       INTERVAL '1 hour'
    ) t
    EXCEPT
    SELECT tscol
    FROM mytable;

但此查询并未删除 2016-11-09 18:30:00,2016-11-09 20:15:00 等。因为我使用了例外。

【问题讨论】:

  • “失踪”是什么意思?你有一个应该在那里的日期列表吗?还是有一定的间隔必须遵守?
  • 什么定义了“插槽”?
  • @Dave 是 1 小时间隔
  • 你需要generate_series()(可能还有min()max()date_trunc()NOT EXISTS(...)
  • @wildplasser 我用示例查询更新了我的问题你能帮忙查询吗?

标签: postgresql


【解决方案1】:

这不是一个孤岛问题。您只想查找表中不存在记录的 1 小时间隔。

EXCEPT 在这里不起作用,因为它会进行相等比较,而您想检查记录是否存在范围内。

一个典型的解决方案是使用左连接反模式:

select dt
from generate_series(
    timestamp with time zone '2016-11-09 18:00:00',
    timestamp with time zone '2016-11-09 23:00:00',
    interval '1 hour'
) d(dt)
left join mytable t
    on t.tscol >= dt and t.tscol < dt + interval '1 hour'
where t.tscol is null

你也可以使用not exists:

select dt
from generate_series(
    timestamp with time zone '2016-11-09 18:00:00',
    timestamp with time zone '2016-11-09 23:00:00',
    interval '1 hour'
) d(dt)
where not exists (
    select 1
    from mytable t
    where t.tscol >= dt and t.tscol < dt + interval '1 hour'
)

在这个demo on DB Fiddle中,两个查询都返回:

| dt | | :--------------------- | | 2016-11-09 21:00:00+00 |

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-20
    • 2021-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多