0

我有一个这样定义的表

                               Table "public.foo"
  Column  |  Type   | Collation | Nullable |               Default               
----------+---------+-----------+----------+-------------------------------------
 foo_id   | integer |           | not null | nextval('foo_foo_id_seq'::regclass)
 bar_id   | integer |           |          | 
 approved | boolean |           |          | 
Indexes:
    "foo_pkey" PRIMARY KEY, btree (foo_id)
Foreign-key constraints:
    "foo_bar_id_fkey" FOREIGN KEY (bar_id) REFERENCES bar(bar_id)

我将如何定义一个排除约束,这样只有一行foo具有特定的bar_id才能设置approved为 true?

例如以下数据:

 foo_id | bar_id | approved 
--------+--------+----------
      1 |      1 | t
      2 |      1 | 
      3 |      2 | 
(3 rows)

我将能够将第 3 行设置approved为 true,因为没有其他行foo_id3 具有 true 以获得批准。

但是,将第 2 行更新approved为 true 会失败,因为第 1 行也有foo_id1 并且已经被批准。

4

2 回答 2

3

您不需要排除约束,过滤的唯一索引可以:

create unique index only_one_approved_bar 
   on foo (bar_id)
   where approved;

我还建议定义approvednot null. 允许null值的布尔列通常是不断混淆的根源。

于 2021-04-13T18:56:01.437 回答
1

尝试这个

ALTER TABLE public.foo
ADD CONSTRAINT uniq_approved UNIQUE (bar_id, approved)

或者您可以创建唯一索引

CREATE UNIQUE INDEX uniq_approved ON public.foo
USING btree (bar_id, approved)
WHERE approved
于 2021-04-13T18:55:53.200 回答