PSQL:使用日期范围表,如何计算与所选日期范围重叠的时间

时间:2017-10-11 14:46:19

标签: sql postgresql

我有一个类似于此的日期范围表,我称之为Attempts

id   |           start            |            end
-----+----------------------------+----------------------------
 1   | 2017-09-09 01:09:00        | 2017-09-09 02:09:00
58   | 2017-09-09 08:35:51.420588 | 2017-09-09 17:01:57.106442
59   | 2017-09-09 17:12:13.644954 | 2017-09-09 17:17:42.186903
60   | 2017-09-09 17:18:51.794184 | 2017-09-09 17:50:09.508929
61   | 2017-09-09 17:19:31.205516 | 2017-09-09 17:20:11.924069
62   | 2017-09-09 17:20:32.320789 | 2017-09-09 17:23:19.973078
63   | 2017-09-09 17:23:53.849006 | 2017-09-09 17:24:23.574369
64   | 2017-09-09 17:24:56.333346 | 2017-09-09 17:27:10.556657
65   | 2017-09-09 17:27:12.605315 | 2017-09-09 17:27:14.680357

我想创建一个查询,该查询将返回该表中的重叠时间总量以及提供的日期范围。例如,我想获得9月份的尝试总时间。

1 个答案:

答案 0 :(得分:1)

WHERE "start" < range_end AND "end" > range_start 中放置参数。

首先,您需要检查行是否与您的范围重叠

CASE WHEN "start" < range_start 
     THEN range_start
     ELSE "start"
END as new_start

但如果该行超出该范围,则重新指定范围边界

SUM (EXTRACT(EPOCH FROM (new_end - new_start)))

然后总结秒数时间戳

WITH input_range as (
    SELECT '2017-09-09 17:18'::timestamp as range_start,
           '2017-09-09 17:22'::timestamp as range_end
), fix_data as (
    SELECT A.*, CASE WHEN "start" < range_start 
                     THEN range_start
                     ELSE "start"
                END as new_start
              , CASE WHEN "end" > range_end 
                     THEN range_end
                     ELSE "end"
                END as new_end    
    FROM Attempts A
    CROSS JOIN input_range
    WHERE "start" < range_end
      AND "end"   > range_start
)
SELECT SUM (EXTRACT(EPOCH FROM (new_end - new_start)))
      -- * to see what are you SUM
FROM fix_data;

Select Case

OneTimeSetUpAttribute