PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Restrição Postgres garantindo que uma coluna de muitas esteja presente?


Atualização de 17/09/2021 :a partir de hoje, gerardnll fornece uma resposta melhor (a melhor IMO) :

Para ajudar as pessoas a encontrar a solução mais limpa, recomendo que você vote na resposta de gerardnll .

(Para sua informação, sou a mesma pessoa que fez a pergunta original.)

Aqui está minha resposta original de 2013


Aqui está uma solução elegante de duas colunas de acordo com a "constraint -- one ou a outra coluna não é nula" quadro de mensagens do PostgreSQL :
ALTER TABLE my_table ADD CONSTRAINT my_constraint CHECK (
  (column_1 IS NULL) != (column_2 IS NULL));

(Mas a abordagem acima não é generalizável para três ou mais colunas.)

Se você tiver três ou mais colunas, poderá usar a abordagem da tabela verdade ilustrada por a_horse_with_no_name . No entanto, considero o seguinte mais fácil de manter porque você não precisa digitar as combinações lógicas:
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;

Para compactar isso, seria útil criar uma função personalizada para que o CASE WHEN column_k IS NULL THEN 0 ELSE 1 END clichê pode ser removido, deixando algo como:
(non_null_count(column_1) +
non_null_count(column_2) +
non_null_count(column_3)) = 1

Isso pode ser tão compacto quanto o PSQL permitirá (?). Dito isso, prefiro chegar a esse tipo de sintaxe, se possível:
non_null_count(column_1, column_2, column_3) = 1