我有一个桌子结构如下:
create table schedule_tab
(
schedule_id serial
primary key,
user_id integer not null,
type varchar(64) not null,
start_date timestamp not null,
end_date timestamp not null
);
insert into schedule_tab (user_id, type, start_date, end_date) values
(1, 'AVAIL', '2023-01-04 06:00:00', '2023-01-04 22:00:00'),
(1, 'AVAIL', '2023-01-05 06:00:00', '2023-01-05 22:00:00'),
(1, 'AVAIL', '2023-01-06 06:00:00', '2023-01-06 22:00:00'),
(1, 'BUSY', '2023-01-04 08:00:00', '2023-01-04 12:00:00'),
(1, 'BUSY', '2023-01-05 17:00:00', '2023-01-05 23:00:00');可以准备一个SQL (PostgreSQL 12.6),当特定用户可用时,该查询返回用户的实际插槽。类型为AVAIL的记录表示用户可用性。另一方面,BUSY显示的是用户已经被预留的时间。
例如,对于日期: 2023-01-04,应该返回6:00-8:00和12:00-22:00之间的两个插槽,因为在8:00-12:00之间我的用户很忙。
发布于 2023-01-30 07:40:10
如果升级到PostgreSQL v14,使用multiranges将非常简单:
SELECT range_agg(tsrange(start_date, end_date)) FILTER (WHERE type = 'AVAIL')
- range_agg(tsrange(start_date, end_date)) FILTER (WHERE type = 'BUSY')
FROM schedule_tab;如果你想把多个射程分开:
SELECT lower(q2.range) AS available_from,
upper(q2.range) AS available_to
FROM (SELECT range_agg(tsrange(start_date, end_date)) FILTER (WHERE type = 'AVAIL')
- range_agg(tsrange(start_date, end_date)) FILTER (WHERE type = 'BUSY') AS ranges
FROM schedule_tab) AS q1
CROSS JOIN LATERAL unnest(q1.ranges) AS q2(range);
available_from │ available_to
═════════════════════╪═════════════════════
2023-01-04 06:00:00 │ 2023-01-04 08:00:00
2023-01-04 12:00:00 │ 2023-01-04 22:00:00
2023-01-05 06:00:00 │ 2023-01-05 17:00:00
2023-01-06 06:00:00 │ 2023-01-06 22:00:00
(4 rows)https://dba.stackexchange.com/questions/322730
复制相似问题