【问题标题】:Postgres - Splitting a row into multiple rows based on two datetime fields to get logged minutes each hourPostgres - 根据两个日期时间字段将一行拆分为多行以获取每小时记录的分钟数
【发布时间】:2021-04-05 02:24:35
【问题描述】:

我想要实现的目标。

我有一个名为 calls 的表,其中包含 started_at:datetimeend_at:datetimehandler:string 列。

id started_at end_at handler agent_id
1 2021-04-05T02:00:00Z 2021-04-05T03:30:00Z fg456fghj 1
2 2021-04-05T03:40:00Z 2021-04-05T04:30:00Z cvbnmfghh 1
3 2021-04-05T04:40:00Z 2021-04-05T05:00:00Z wertyuuuu 1
4 2021-04-06T01:40:00Z 2021-04-05T02:00:00Z 34sdfertt 1

我想要一个像这样的新表

id hour minutes_logged
1 02 of 2021-04-05 60
2 03 of 2021-04-05 50
3 04 of 2021-04-05 50
4 01 of 2021-04-06 20

注意minutes_logged 不能超过 60 分钟,因为一个小时只有 60 分钟。


我的发现

对于hour 专栏,我可以写的是

concat(extract(hour from calls.started_at), ' of ', calls.started_at::date) as hour

但我无法正确地为minutes_logged 写信。

主要问题

我无法编写查询来将时间范围分成多行。请帮忙。我感谢你的努力。提前致谢。

【问题讨论】:

    标签: postgresql


    【解决方案1】:

    我们可以通过首先生成一个涵盖数据集中所有日期的所有分钟的日历表来解决此问题。然后,内部连接到您的数据表并按小时(和天)聚合以生成计数:

    WITH dates AS (
        SELECT '2021-04-05'::date AS dt UNION ALL
        SELECT '2021-04-06'::date
    ),
    minutes AS (
        SELECT (n || ' minute')::INTERVAL AS min
        FROM generate_series(0, 1439) n
    )
    
    SELECT
        DATE_TRUNC('hour', d.dt + m.min),
        COUNT(*) AS minutes_logged
    FROM dates d
    CROSS JOIN minutes m
    INNER JOIN yourTable t
       ON d.dt + m.min >= t.started_at AND d.dt + m.min < t.end_at
    GROUP BY DATE_TRUNC('hour', d.dt + m.min)
    ORDER BY DATE_TRUNC('hour', d.dt + m.min);
    

    Demo


    注意:为了支持广泛的开始和结束日期,可以实现以下

    
        with dates AS (
            select * from generate_series(timestamp '2019-12-08'::date, '2021-04-09'::date, '1 day') as dt
        ),
    

    【讨论】:

    • Tim,这个解决方案对于大型数据库似乎效率低下。因为我的生产表中有数百万条记录。您能否也发布一个耗时较少的解决方案?
    • 不,我不能这样做,因为除了我上面发布的内容之外,我不知道其他解决方案。您也许可以尝试索引您的表:CREATE INDEX idx ON yourTable (started_at, end_at) ...这至少可以加快日历表和数据表之间的连接。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多