我有一個適用于雙重預訂的預訂系統。一個人為 tsrange 預訂了一個房間,然后可以在該房間預訂的基礎上進行預約。我能夠使約束正常作業,當然約會的 tsrange 必須包含在保留 tsrange 中。
現在,我需要一個查詢,該查詢回傳預留空閑范圍的 tsranges[],即當時尚未進行任何約會,但我不知道該怎么做……嗯,我有一個粗略的關于如何在 plpgsql 回圈約會中實作這一點的想法,但我想知道是否有更優雅的純 SQL 解決方案,也許使用遞回 CTE 或視窗函式?
例如,考慮我在 range: 上有保留'[2010-01-01 08:00, 2010-01-01 18:00)'。
以及該保留的以下約會: '[2010-01-01 08:00, 2010-01-01 09:00)';'[2010-01-01 11:00, 2010-01-01 12:00)';'[2010-01-01 14:00, 2010-01-01 17:00)'
此類函式的輸出類似于: '[2010-01-01 09:00, 2010-01-01 11:00)','[2010-01-01 12:00, 2010-01-01 14:00)','[2010-01-01 17:00, 2010-01-01 18:00)'
這是一個帶有簡化架構的示例dbfiddle:
create table reservation (
id numeric,
room_id numeric,
during tsrange
);
create table appointment (
id serial,
on_reservation numeric,
during tsrange
);
insert into reservation (id, room_id, during)
VALUES (1, 1, '[2010-01-01 08:00, 2010-01-01 18:00)');
insert into appointment (id, on_reservation, during)
VALUES (2, 1, '[2010-01-01 08:00, 2010-01-01 09:00)');
insert into appointment (id, on_reservation, during)
VALUES (3, 1, '[2010-01-01 10:00, 2010-01-01 12:00)');
insert into appointment (id, on_reservation, during)
VALUES (4, 1, '[2010-01-01 14:00, 2010-01-01 17:00)');
我仍然不熟悉 pg14 中添加的多范圍支持,但如果這讓事情變得更容易,我可以升級......
uj5u.com熱心網友回復:
使用 PostgreSQL v14 和您的資料模型,這可能就像
SELECT r.id,
/* convert the reservation to a multirange */
tsmultirange(r.during)
-
/* aggregate the appointments to a multirange */
range_agg(a.during)
AS free_slots
FROM reservation AS r
JOIN appointment AS a ON a.on_reservation = r.id
GROUP BY r.id, r.during;
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/340192.html
標籤:PostgreSQL 范围 公用表表达式 窗函数
