对特定文本的唯一约束
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
我有以下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