[英]postgreSQL - Checking if one date interval does not overlap a date interval in array of intervals for each row
PostgreSQL(9.6), I am trying to check whether a date interval PostgreSQL(9.6),我正在尝试检查日期间隔
('2018-11-18 12:00','2018-11-20 12:00')
does not overlap any of the following date intervals in the array 不与数组中的以下任何日期间隔重叠
{('2018-11-21 12:00','2018-11-23 12:00'),('2018-11-19 12:00','2018-11-20 12:00')}
The elements in the array are composite: 数组中的元素是复合的:
CREATE TYPE reservation AS (
checkIn TIMESTAMP WITHOUT TIME ZONE,
checkOut TIMESTAMP WITHOUT TIME ZONE
)
Here is the rooms table: 这是房间表:
CREATE TABLE rooms (
rId roomId PRIMARY KEY,
hRef hotelId NOT NULL,
rNo roomNo NOT NULL,
rType roomType,
numPeople INTEGER,
rBedOptions roomBed[],
reservations reservation[],
priceNight FLOAT,
FOREIGN KEY (hRef) REFERENCES hotels(hId) ON UPDATE CASCADE ON DELETE SET NULL
)
INSERT INTO rooms VALUES
('R001','H001','101','one-bedroom',1,
ARRAY[row('1 twin')::roomBed],
ARRAY[
row('2018-11-21 12:00','2018-11-23 12:00')::reservation,
row('2018-11-19 12:00','2018-11-20 12:00')::reservation],
450.5);
Basically I am trying to check whether a "room" is available for a selected time interval by checking if this interval does not overlap with any existing reservation date intervals ('2018-11-21 12:00','2018-11-23 12:00'),('2018-11-19 12:00','2018-11-20 12:00'). 基本上,我正在尝试通过检查此时间间隔是否与任何现有的预订日期时间间隔不重叠来检查选定时间间隔是否有“房间”('2018-11-21 12:00','2018-11-23 12:00'),('2018-11-19 12:00','2018-11-20 12:00')。 So far I have been successful in checking the first element of the array for each row by writing the following query:
到目前为止,通过编写以下查询,我已经成功地检查了每一行的数组的第一个元素:
SELECT * FROM rooms R
WHERE R.reservations[1] IS null
OR NOT (('2018-11-18 12:00','2018-11-20 12:00')
OVERLAPS (R.reservations[1].checkIn, R.reservations[1].checkOut))
ORDER BY rid;
The problem is that I don't know how to check all elements in the array if there is more than one. 问题是,如果有多个元素,我不知道如何检查数组中的所有元素。 Any ideas or suggestions?
有什么想法或建议吗?
unnest
to transform array into row on the fly unnest
快速将数组转换为行 SELECT *
FROM rooms R,
LATERAL (SELECT bool_or(
('2018-11-18 12:00','2018-11-20 12:00')
OVERLAPS (periods.checkIn, periods.checkOut)
) as someone_overlaps
FROM unnest(R.reservations) periods
) ok
WHERE someone_overlaps is not true
ORDER BY rid;
OR
of each overlap, take it in the someone_overlapas
OR
,将其放入someone_overlapas
someone_overlapas
someone_overlapas
每一行 true
, false
and null
thats why is not the same not someone_overlaps
that someone_overlaps is not true
, in the first case the null
value remains null
in the seconds null is not true
. true
, false
和null
这就是为什么不一样的原因not someone_overlaps
that someone_overlaps is not true
,在第一种情况下null
值在几秒钟内仍为null
null is not true
。 The second is used because the reservations may be an empty array. Lateral
a keyword that allows to use previous tables (in the from list) to be used in the curren subselct Lateral
关键字,允许使用当前表(在from列表中)在curren subselct中使用 unnest
a function that transforms array into row unnest
将数组转换为行的函数
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.