我正在创建一个用于预订酒店房间的数据库。我停留在一个约束上,该约束检查guest虚拟机的'dateFrom'变量是否在该特定guest虚拟机的任何'dateFrom'和'dateTo'变量之间。即)客人不能一次预订超过1个房间。
我收到错误:“无法在检查约束中使用子查询”:
CREATE TABLE tomsBooking
(
hotelNo HotelNo NOT NULL,
guestNo INT NOT NULL,
dateFrom DATE NOT NULL,
dateTo DATE NOT NULL,
roomNo RoomNumber
CONSTRAINT GuestOverlap
CHECK ( NOT EXISTS
(SELECT * FROM tomsBooking b
WHERE b.guestNo = b.guestNo
AND b.dateTo >= dateFrom
AND b.dateFrom <= dateTo
)
)
);
答案 0 :(得分:4)
不幸的是,Postgres不支持检查约束的子查询。
但是这种情况正是exclusion constraints创建的地方:
CREATE TABLE tomsBooking
(
hotelNo HotelNo NOT NULL,
guestNo INT NOT NULL,
dateFrom DATE NOT NULL,
dateTo DATE NOT NULL,
roomNo RoomNumber
);
alter table tomsbooking
add constraint guestoverlap
exclude using gist (guestno with =, daterange(datefrom, dateto) with &&);
有关详细信息和示例,请参阅手册:https://www.postgresql.org/docs/current/static/rangetypes.html#RANGETYPES-CONSTRAINT
为了使GIST索引能够使用=
运算符,您需要使用以下命令安装btree_gist模块:
create extension btree_gist;
(每个数据库只需要执行一次)
答案 1 :(得分:0)
请记住,我不知道Postgres SQL ......在我看来,您需要在BETWEEN语句附近使用术语VALUE,以便比较知道它在哪个值之间进行检查。
作为替代方案,并且基于Postgresql query between date ranges,我会将其构造为:
CREATE DOMAIN DateFrom AS DATE
CHECK (VALUE > '2016-10-16' AND NOT EXISTS (SELECT * FROM tomsBooking b
WHERE b.guestNo = g.guestNo
AND VALUE >= dateFrom
AND VALUE <= dateTo
)
);
正如我所说,我不了解Postgres,所以你可能需要调整我的建议。