2021-09-17アップデート :今日の時点で、 gerardnllがより良い答え(最高のIMO)を提供します :
人々が最もクリーンな解決策を見つけるのを助けるために、gerardnllの答え に賛成することをお勧めします 。
(参考までに、私は元の質問をしたのと同じ人です。)
これが2013年の私の最初の答えです
これは、"constraint--1によるエレガントな2列のソリューションです。または他の列がnullではない"PostgreSQLメッセージボード :
ALTER TABLE my_table ADD CONSTRAINT my_constraint CHECK (
(column_1 IS NULL) != (column_2 IS NULL));
(ただし、上記のアプローチは3つ以上の列に一般化することはできません。)
3つ以上の列がある場合は、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