在postgresql中查找两个时间戳之间的重叠时间

在postgresql中查找两个时间戳之间的重叠时间,sql,postgresql,date,datetime,group-by,Sql,Postgresql,Date,Datetime,Group By,我在postgers中有一个与此模式类似的表 id start_time end_time 1 2019-10-21 20:00:00 UTC 2019-10-21 23:00:00 UTC 2 2019-10-21 22:00:00 UTC 2019-10-22 02:00:00 UTC 我想写一个查询,它将在数据库中给我重叠的持续时间 例如:给定两个输入 t1=2019-10-21 21:00:00 UTC t2=2019

我在postgers中有一个与此模式类似的表

id            start_time            end_time
1    2019-10-21 20:00:00 UTC    2019-10-21 23:00:00 UTC
2    2019-10-21 22:00:00 UTC    2019-10-22 02:00:00 UTC
我想写一个查询,它将在数据库中给我重叠的持续时间

例如:给定两个输入 t1=2019-10-21 21:00:00 UTC t2=2019-10-22 01:00:00 UTC 查询应计算输入范围之间的所有重叠时间

输入和行1之间的重叠时间为2小时 输入和第2行之间的重叠时间为3小时
结果是2+3=5,听起来好像你在寻找两个值的交集:

“[]”指定两条边都应包含在该范围内。这可能是你想要的,也可能不是。您需要根据自己的要求进行调整

这将返回一个范围类型。要计算范围的长度,请从下限值中减去上限值:

select sum(upper(diff) - lower(diff))
from (
   select tsrange(start_time, end_time, '[]') * tsrange('2019-10-21 21:00:00', '2019-10-22 01:00:00', '[]') as diff
   from the_table
) t
这将返回一个表示所有重叠总和的值

如果列是带时区的时间戳,则需要改用tstzrange


听起来好像您在寻找两个值的交点:

“[]”指定两条边都应包含在该范围内。这可能是你想要的,也可能不是。您需要根据自己的要求进行调整

这将返回一个范围类型。要计算范围的长度,请从下限值中减去上限值:

select sum(upper(diff) - lower(diff))
from (
   select tsrange(start_time, end_time, '[]') * tsrange('2019-10-21 21:00:00', '2019-10-22 01:00:00', '[]') as diff
   from the_table
) t
这将返回一个表示所有重叠总和的值

如果列是带时区的时间戳,则需要改用tstzrange


您可以使用日期算术和聚合:

select 
    sum(
        greatest(
            least(d.end_time, t.end_time) - greatest(d.start_time, t.start_time), 
            '0 hour'::interval
        )
    ) total_overlap
from mytable t
cross join (values 
    ('2019-10-21 21:00:00'::timestamp, '2019-10-22 01:00:00'::timestamp)
) d(start_time, end_time)

对于每一行,较小的结束时间和最大的开始时间之间的差值给出重叠的持续时间(如果是正值)

您可以使用日期算术和聚合:

select 
    sum(
        greatest(
            least(d.end_time, t.end_time) - greatest(d.start_time, t.start_time), 
            '0 hour'::interval
        )
    ) total_overlap
from mytable t
cross join (values 
    ('2019-10-21 21:00:00'::timestamp, '2019-10-22 01:00:00'::timestamp)
) d(start_time, end_time)

对于每一行,较小的结束时间和最大的开始时间之间的差值给出重叠的持续时间(如果是正值)

我不明白为什么第二排的重叠时间应该是4小时。对我来说,从22:00到次日01:00只有三个小时是的,应该是3点。编辑问题。谢谢,我不明白为什么第二排的重叠时间应该是4小时。对我来说,从22:00到次日01:00只有三个小时是的,应该是3点。编辑问题。感谢对于像10k行这样的行,在数据库本身或应用程序中进行此计算在性能方面是最好的吗?对于像10k行这样的行,在数据库本身或应用程序中进行此计算在性能方面是最好的吗?