21-09-17 update :Vanaf vandaag geeft gerardnll een beter antwoord (de beste IMO) :
Om mensen te helpen de schoonste oplossing te vinden, raad ik je aan om gerardnll's antwoord te upvoten. .
(Ter info, ik ben dezelfde persoon die de oorspronkelijke vraag stelde.)
Hier is mijn oorspronkelijke antwoord uit 2013
Hier is een elegante oplossing met twee kolommen volgens de "beperking -- een of de andere kolom niet null" PostgreSQL-prikbord :
ALTER TABLE my_table ADD CONSTRAINT my_constraint CHECK (
(column_1 IS NULL) != (column_2 IS NULL));
(Maar de bovenstaande benadering is niet generaliseerbaar naar drie of meer kolommen.)
Als u drie of meer kolommen heeft, kunt u de waarheidstabelbenadering gebruiken, geïllustreerd door a_horse_with_no_name . Ik beschouw het volgende echter als gemakkelijker te onderhouden omdat je de logische combinaties niet hoeft over te typen:
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;
Om dit te comprimeren, zou het handig zijn om een aangepaste functie te maken zodat de CASE WHEN column_k IS NULL THEN 0 ELSE 1 END
standaardtekst kan worden verwijderd, waardoor er iets overblijft als:
(non_null_count(column_1) +
non_null_count(column_2) +
non_null_count(column_3)) = 1
Dat kan zo compact zijn als PSQL toestaat (?). Dat gezegd hebbende, zou ik, indien mogelijk, de voorkeur geven aan dit soort syntaxis:
non_null_count(column_1, column_2, column_3) = 1