这里的挑战是使用SQL来使用日期/时间检测重叠的出价,并显示它与哪些出价重叠。
考虑表和记录:
-------------------------------------------------------------------
| person_id | bid_id | start_at | end_at |
-------------------------------------------------------------------
| 1 | 10 | 2016-10-30 09:00 AM | 2016-10-30 11:00 AM |
| 1 | 20 | 2016-10-30 10:00 AM | 2016-10-30 12:00 PM |
| 1 | 30 | 2016-10-30 05:00 PM | 2016-10-30 06:00 PM |
| 1 | 40 | 2016-10-30 11:45 AM | 2016-10-30 02:00 PM |
| 2 | 50 | 2016-10-30 07:00 PM | 2016-10-30 08:00 PM |
| 2 | 60 | 2016-10-30 07:00 PM | 2016-10-30 08:00 PM |
| 2 | 70 | 2016-10-30 09:00 PM | 2016-10-30 10:00 PM |
-------------------------------------------------------------------
期望的输出:
--------------------------------------------
| person_id | bid_id | overlapping_bid_ids |
--------------------------------------------
| 1 | 10 | { 20 } |
| 1 | 20 | { 10, 40 } |
| 1 | 40 | { 20 } |
| 2 | 50 | { 60 } |
| 2 | 60 | { 50 } |
--------------------------------------------
答案 0 :(得分:2)
您可以使用array_agg()
和加入:
select b.person_id, b.bid_id, array_agg(b2.bid_id)
from bids b join
bids b2
on b2.person_id = b.person_id and
b2.end_at > b.start_at and
b2.start_at < b.end_at and
b2.bid_id <> b.bid_id
group by b.person_id, b.bid_id;
请注意两个时间段重叠的逻辑。如果第一个在第二个结束之前开始而第一个结束在第一次结束之后开始,则它们重叠。这解释了部分重叠以及完全重叠。如果您愿意,也可以使用Postgres的ANSI标准范围运算符overlap
的实现。