具有多个条件的SQL检查约束
我有一张叫时间表的桌子。在该表中有4列,我想为其创建一个约束,以便只有以下组合是可能的:具有多个条件的SQL检查约束,sql,postgresql,check-constraints,Sql,Postgresql,Check Constraints,我有一张叫时间表的桌子。在该表中有4列,我想为其创建一个约束,以便只有以下组合是可能的: 如果设置了user\u,则task\u schedule\u id必须为空 如果设置了location\u id或customer\u id,则要求user\u id不为空,并确保未同时设置location\u id和customer\u id 如果设置了task\u schedule\u id,则要求user\u id、customer\u id和location\u id为空 这是表格: CREAT
- 如果设置了
,则user\u
必须为空task\u schedule\u id
- 如果设置了
或location\u id
,则要求customer\u id
不为空,并确保未同时设置user\u id
和location\u id
customer\u id
- 如果设置了
,则要求task\u schedule\u id
、user\u id
和customer\u id
为空location\u id
CREATE TABLE IF NOT EXISTS timesheets
(
id uuid NOT NULL DEFAULT gen_random_uuid(),
created_at timestamptz NOT NULL DEFAULT current_timestamp,
updated_at timestamptz NOT NULL DEFAULT current_timestamp,
deleted_at timestamptz NULL,
-- Where and who (check if location_id or customer_id is set then require user)
location_id uuid NULL,
customer_id uuid NULL,
user_id uuid NULL,
-- Or what... BUT not both
task_schedule_id uuid NULL,
-- Billing
billable bool NOT NULL DEFAULT TRUE,
billed_at timestamptz NULL,
-- fks and pk
FOREIGN KEY (user_id) REFERENCES users (id),
FOREIGN KEY (task_schedule_id) REFERENCES task_schedules (id),
FOREIGN KEY (location_id) REFERENCES locations (id),
FOREIGN KEY (customer_id) REFERENCES customers (id),
PRIMARY KEY (id)
);
这就是我到目前为止所做的:
ALTER TABLE timesheets
ADD constraint only_one_group
check (
((user_id is null and customer_id is null and location_id is null) and
task_schedule_id is not null)
or
(user_id is not null and not (customer_id is null and location_id is null) and
(customer_id is null or location_id is null) and
task_schedule_id is null)
);
上下文是一个任务计划链接到一个任务,该任务可以包含一个位置id和/或一个客户id。其思想是时间表可以全局创建,也可以与任务一起创建。您可以将约束写为:
ALTER TABLE timesheets
ADD constraint just_user__or__location_or_customer_with_user__or__just_task check (
(
user_id is not null
and task_schedule_id is null
and (
(location_id is null and customer_id is null)
and (location_id is not null or customer_id is not null)
)
) or (
(location_id is not null or customer_id is not null)
and not (location_id is not null and customer_id is not null)
and user_id is not null
) or (
task_schedule_id is not null
and user_id is null
and location_id is null
and customer_id is null
)
);
@汤姆,请看修改后的解决方案,