我无法在查询中组合相邻的时间段

问题描述 投票:0回答:1

我在 PostgreSQL 工作。

我有一个表,用于存储有关客户及其在不同组中的状态的信息。我想要一个选择查询来显示这些信息,例如句点而不是事件结构。因此它将显示 client_id、moment_start、moment_end、status_group 和 status(布尔值)。虽然我可以使用 Lead(),但我得到的结果是客户端的下一个具有相同状态的周期是另一条记录,而我想要获取状态从行到行发生变化的周期(通过 client_id 和 status_group)。实际上,我使用时间戳(6)而不是日期。

我应该在查询中写什么来实现这一点?

原表:

id client_id 时刻 状态组 状态
1 1 2021-05-01 A 正确
2 1 2021-05-05 A 正确
3 1 2021-05-07 A 错误
4 1 2021-06-10 A 正确
5 2 2021-07-10 A 正确
6 2 2021-05-10 B 错误

所需表格:

client_id 时刻_开始 时刻_结束 状态组 状态
1 2021-05-01 2021-05-07 A 正确
1 2021-05-07 2021-06-10 A 错误
1 2021-06-10 A 正确
2 2021-07-10 A 正确
2 2021-05-10 B 错误

我尝试过:

SELECT
client_id,
moment AS moment_start
LEAD(moment) OVER (PARTITION BY client_id, group ORDER BY moment) AS moment_end,
status_group,
status
FROM table
ORDER BY client_id, moment_start

我拿到的桌子:

client_id 时刻_开始 时刻_结束 状态组 状态
1 2021-05-01 2021-05-05 A 正确
1 2021-05-05 2021-05-07 A 正确
1 2021-05-07 2021-06-10 A 错误
1 2021-06-10 A 正确
2 2021-07-10 A 正确
2 2021-05-10 B 错误
sql postgresql datetime group-by window-functions
1个回答
0
投票

以下查询演示了一种仅提取状态更改的方法:

WITH
    example_data (id, client_id, moment, status_group, status) AS (
        VALUES
            (1, 1, '2021-05-01'::TIMESTAMP, 'A', TRUE),
            (2, 1, '2021-05-05'::TIMESTAMP, 'A', TRUE),
            (3, 1, '2021-05-07'::TIMESTAMP, 'A', FALSE),
            (4, 1, '2021-06-10'::TIMESTAMP, 'A', TRUE),
            (5, 2, '2021-07-10'::TIMESTAMP, 'A', TRUE),
            (6, 2, '2021-05-10'::TIMESTAMP, 'B', FALSE)
    ),
    changes AS (
        SELECT
            d.id,
            d.client_id,
            d.moment,
            d.status_group,
            d.status,
            (d.status_group, d.status) IS DISTINCT FROM (LAG(d.status_group) OVER client_moment,
                                                         LAG(d.status) OVER client_moment) AS client_status_changed
        FROM
            example_data d
        WINDOW
            client_moment AS (PARTITION BY d.client_id, d.status_group ORDER BY d.moment)
    )
SELECT
    c.client_id,
    c.moment,
    c.status_group,
    c.status
FROM
    changes c
WHERE
    c.client_status_changed
ORDER BY
    c.client_id, c.moment;

产生以下结果:

client_id 瞬间 状态组 状态
1 2021-05-01 00:00:00 A 真实
1 2021-05-07 00:00:00 A
1 2021-06-10 00:00:00 A 真实
2 2021-05-10 00:00:00 B
2 2021-07-10 00:00:00 A 真实

查询使用命名窗口框架来减少冗余代码。通过使用主查询中的

moment_start
函数,可以轻松修改查询以返回包括
moment_end
LAG

© www.soinside.com 2019 - 2024. All rights reserved.