特定文本的唯一约束

时间:2017-08-10 11:53:18

标签: sql postgresql unique

我有下表

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')一样的Smth 我对Postgres非常感兴趣。提前致谢

2 个答案:

答案 0 :(得分:1)

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

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) 
);

答案 1 :(得分:1)

create unique index some_name on "order" (user_id, (case when status = 'requested' then 1 else null end));

背后的想法是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