Postgres constraint ensuring one column of many is present?

前端 未结 6 1507
天命终不由人
天命终不由人 2021-02-01 03:01

What are good ways to add a constraint to PostgreSQL to check that exactly one column (from a set of columns) contains a non-null value?

Update: It is likely th

6条回答
  •  -上瘾入骨i
    2021-02-01 03:50

    Here is an elegant two column solution according to the "constraint -- one or the other column not null" PostgreSQL message board:

    ALTER TABLE my_table ADD CONSTRAINT my_constraint CHECK (
      (column_1 IS NULL) != (column_2 IS NULL));
    

    (But the above approach is not generalizable to three or more columns.)

    If you have three or more columns, you can use the truth table approach illustrated by a_horse_with_no_name. However, I consider the following to be easier to maintain because you don't have to type out the logical combinations:

    ALTER TABLE my_table
    ADD CONSTRAINT my_constraint CHECK (
      (CASE WHEN column_1 IS NULL THEN 0 ELSE 1 END) +
      (CASE WHEN column_2 IS NULL THEN 0 ELSE 1 END) +
      (CASE WHEN column_3 IS NULL THEN 0 ELSE 1 END) = 1;
    

    To compact this, it would be useful to create a custom function so that the CASE WHEN column_k IS NULL THEN 0 ELSE 1 END boilerplate could be removed, leaving something like:

    (non_null_count(column_1) +
    non_null_count(column_2) +
    non_null_count(column_3)) = 1
    

    That may be as compact as PSQL will allow (?). That said, I'd prefer to get to this kind of syntax if possible:

    non_null_count(column_1, column_2, column_3) = 1
    

提交回复
热议问题