对特定文本的唯一约束

Unique constraint to specific text

我有以下table

create table order(
status text,
user_id int (FK to user table),
time time stamp with time zone

);

以及以下状态约束

CONSTRAINT valid_status CHECK (status = ANY (ARRAY['requested'::text, 'accepted'::text, 'declined_by_manager'::text, 'declined_by_user'::text, 'finished_by_user'::text, 'canceled_by_system'::text, 'washing'::text, 'finished_by_manager'::text]))

我想要的是,只能有一个状态为“已请求”且用户为 "n" 的订单 好像 Alter table order add constraint "only_one_order_per_user" UNIQUE(user_id, status = 'requested') 我真的是 Postgres 的新手。提前致谢

试试这个。您应该能够构建 table 以便您只能拥有请求的状态,但不确定是否允许 NULL。然后为 user_id 和状态添加一个唯一值。

create table order(
status text CHECK (status in ('requested'[add more statuses here])) ,
user_id int,
time time stamp with time zone
UNIQUE (status, user_id) 
);
create unique index some_name on "order" (user_id, (case when status = 'requested' then 1 else null end));

null <> null

背后的想法

也许您最好使用 ENUM 作为状态?..或者甚至更好地创建具有不同行和 FK 的关系状态?..

示例:

t=# create table "order" (
status text,
user_id int,
time timestamp with time zone
);
CREATE TABLE
Time: 6.345 ms
t=# create unique index some_name on "order" (user_id, (case when status = 'requested' then 1 else null end));
CREATE INDEX
Time: 16.979 ms
t=# insert into "order" select 'requested',1,now();
INSERT 0 1
Time: 17.793 ms
t=# insert into "order" select 'other',1,now();
INSERT 0 1
Time: 1.137 ms
t=# insert into "order" select 'other',1,now();
INSERT 0 1
Time: 6.735 ms
t=# insert into "order" select 'other',1,now();
INSERT 0 1
Time: 0.867 ms
t=# insert into "order" select 'requested',1,now();
ERROR:  duplicate key value violates unique constraint "some_name"
DETAIL:  Key (user_id, (
CASE
    WHEN status = 'requested'::text THEN 1
    ELSE NULL::integer
END))=(1, 1) already exists.
Time: 0.342 ms