我有一些时间段:
Mobile Event Time
A START 13:00
B START 13:05
A STOP 14:00
B STOP 14:05
A START 15:00
A STOP 16:00
我如何对这些数据进行逻辑运算,以便我得到:
Mobile Event Time
A | B START 13:00
A | B STOP 14:05
A | B START 15:00
A | B STOP 16:00
和
Mobile Event Time
A & B START 13:05
A & B STOP 14:00
答案 0 :(得分:1)
如果我理解你的要求,那么"逻辑运算"可能不是描述这些的最佳方式;他们确实设置了交叉和联合操作(尽管两者密切相关)。
的Postgres' range operators可以计算联合和交叉点,因此可能有助于首先将开始/结束时间戳(如your previous question)配对以构建tsrange
values。
一旦到位,找到交叉点(A & B
)相对简单:
WITH time_pair AS (
SELECT *, lead("time") OVER (PARTITION BY mobile ORDER BY "time") AS next_time
FROM events
WHERE event IN ('START', 'STOP')
),
time_range AS (
SELECT mobile, tsrange("time", next_time) AS period
FROM time_pair
WHERE event = 'START'
)
SELECT 'A & B', a_range.period * b_range.period
FROM time_range a_range
JOIN time_range b_range ON
a_range.period && b_range.period
WHERE
a_range.mobile = 'A' AND
b_range.mobile = 'B';
联盟(A | B
)更多参与;如果一个范围在两端都重叠,则每个输出行都有(至少)三个范围,因此单个JOIN
就不够了。
另一方面,这个问题有点笼统,因为您可以将任何重叠范围合并在一起,而不考虑它们来自哪个用户,因此查找现有实现会更容易一些。 This answer似乎相当全面。您可以通过搜索"postgres range aggregation"找到更多内容。