Актуализация от 2021-09-17 :От днес gerardnll предоставя по-добър отговор (най-добрият IMO) :
За да помогна на хората да намерят най-чистото решение, препоръчвам ви да гласувате за отговора на gerardnll .
(За информация, аз съм същият човек, който зададе първоначалния въпрос.)
Ето моят оригинален отговор от 2013 г.
Ето елегантно решение с две колони според "ограничението -- едно или другата колона не е нула" PostgreSQL табло за съобщения :
ALTER TABLE my_table ADD CONSTRAINT my_constraint CHECK (
(column_1 IS NULL) != (column_2 IS NULL));
(Но горният подход не може да се обобщи за три или повече колони.)
Ако имате три или повече колони, можете да използвате подхода на таблицата на истината, илюстриран от a_horse_with_no_name . Смятам обаче, че следното е по-лесно за поддържане, защото не е необходимо да въвеждате логическите комбинации:
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;
За да компактирате това, би било полезно да създадете персонализирана функция, така че CASE WHEN column_k IS NULL THEN 0 ELSE 1 END
шаблонът може да бъде премахнат, оставяйки нещо като:
(non_null_count(column_1) +
non_null_count(column_2) +
non_null_count(column_3)) = 1
Това може да е толкова компактно, колкото позволява PSQL (?). Въпреки това бих предпочел да стигна до този вид синтаксис, ако е възможно:
non_null_count(column_1, column_2, column_3) = 1