PostgreSQL 从一个日期列构建工作范围

PostgreSQL build working range from one date column

我正在使用 PostgreSQL v. 11.2

我有一个table

|id | bot_id |        date        |
| 1 |  1     | 2020-04-20 16:00:00| 
| 2 |  2     | 2020-04-22 12:00:00| 
| 3 |  3     | 2020-04-24 04:00:00| 
| 4 |  1     | 2020-04-27 09:00:00| 

例如,我有 DateTime 范围 2020-03-30 00:00:002020-04-30 00:00:00

我需要显示获取工作范围来计算每个机器人的总工作时间。

像这样:

|bot_id | start_date          |       end_date       |
| 1     | 2020-03-30 00:00:00 |  2020-04-20 16:00:00 |
| 2     | 2020-04-20 16:00:00 |  2020-04-22 12:00:00 |
| 3     | 2020-04-22 12:00:00 |  2020-04-24 04:00:00 |
| 1     | 2020-04-24 04:00:00 |  2020-04-27 09:00:00 |
| 1     | 2020-04-27 09:00:00 |  2020-04-30 00:00:00 |

我试过使用 LAG(date),但我没有得到该范围的第一个和最后一个日期。

您可以使用 UNION ALL,其中一部分根据您的价值观构建 start_date/end_date 对,另一部分填充最后一个时期(从最后一个 date2020-04-30 00:00:00):

WITH values (id, bot_id, date) AS (
    VALUES (1, 1, '2020-04-20 16:00:00'::TIMESTAMP)
         , (2, 2, '2020-04-22 12:00:00')
         , (3, 3, '2020-04-24 04:00:00')
         , (4, 1, '2020-04-27 09:00:00')
)
(
    SELECT bot_id
         , LAG(date, 1, '2020-03-30 00:00:00') OVER (ORDER BY id) AS start_date
         , date                                                   AS end_date
    FROM values
)
UNION ALL
(
    SELECT bot_id
         , date                  AS start_date
         , '2020-04-30 00:00:00' AS end_date
    FROM values
    ORDER BY id DESC
    LIMIT 1
)

+------+--------------------------+--------------------------+
|bot_id|start_date                |end_date                  |
+------+--------------------------+--------------------------+
|1     |2020-03-30 00:00:00.000000|2020-04-20 16:00:00.000000|
|2     |2020-04-20 16:00:00.000000|2020-04-22 12:00:00.000000|
|3     |2020-04-22 12:00:00.000000|2020-04-24 04:00:00.000000|
|1     |2020-04-24 04:00:00.000000|2020-04-27 09:00:00.000000|
|1     |2020-04-27 09:00:00.000000|2020-04-30 00:00:00.000000|
+------+--------------------------+--------------------------+