Uppdatering 2021-09-17 :Från och med idag ger gerardnll ett bättre svar (den bästa IMO) :
För att hjälpa människor att hitta den renaste lösningen rekommenderar jag att du röstar upp gerardnls svar .
(FYI, jag är samma person som ställde den ursprungliga frågan.)
Här är mitt ursprungliga svar från 2013
Här är en elegant lösning med två kolumner enligt "begränsningen -- en eller den andra kolumnen inte null" PostgreSQL-anslagstavla :
ALTER TABLE my_table ADD CONSTRAINT my_constraint CHECK (
(column_1 IS NULL) != (column_2 IS NULL));
(Men ovanstående tillvägagångssätt är inte generaliserbart till tre eller fler kolumner.)
Om du har tre eller fler kolumner kan du använda sanningstabellsmetoden som illustreras av a_horse_with_no_name . Jag anser dock att följande är lättare att underhålla eftersom du inte behöver skriva ut de logiska kombinationerna:
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;
För att komprimera detta skulle det vara användbart att skapa en anpassad funktion så att CASE WHEN column_k IS NULL THEN 0 ELSE 1 END
pannplattan kan tas bort och lämna något i stil med:
(non_null_count(column_1) +
non_null_count(column_2) +
non_null_count(column_3)) = 1
Det kan vara så kompakt som PSQL tillåter (?). Som sagt, jag föredrar att komma till den här typen av syntax om möjligt:
non_null_count(column_1, column_2, column_3) = 1