sql >> Databáze >  >> RDS >> PostgreSQL

Postgres omezení zajišťující jeden sloupec z mnoha je přítomen?

Aktualizace 2021-09-17 :K dnešnímu dni gerardnll poskytuje lepší odpověď (nejlepší IMO) :

Abyste lidem pomohli najít nejčistší řešení, doporučuji vám hlasovat pro gerardnllovu odpověď .

(Pro informaci, jsem stejná osoba, která položila původní otázku.)

Zde je moje původní odpověď z roku 2013

Zde je elegantní dvousloupcové řešení podle "omezení -- jedna nebo druhý sloupec není null" Nástěnka PostgreSQL :

ALTER TABLE my_table ADD CONSTRAINT my_constraint CHECK (
  (column_1 IS NULL) != (column_2 IS NULL));

(Výše uvedený přístup však nelze zobecnit na tři nebo více sloupců.)

Pokud máte tři nebo více sloupců, můžete použít pravdivostní tabulku znázorněnou a_horse_with_no_name . Nicméně považuji následující za jednodušší na údržbu, protože nemusíte zadávat logické kombinace:

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;

Chcete-li to zkomprimovat, bylo by užitečné vytvořit vlastní funkci tak, aby CASE WHEN column_k IS NULL THEN 0 ELSE 1 END kotelní štítek by mohl být odstraněn a zůstalo by něco jako:

(non_null_count(column_1) +
non_null_count(column_2) +
non_null_count(column_3)) = 1

To může být tak kompaktní, jak to PSQL dovolí (?). To znamená, že bych se raději dostal k tomuto druhu syntaxe, pokud je to možné:

non_null_count(column_1, column_2, column_3) = 1


  1. Cíle MySQL v pracovním postupu Luigi

  2. převést python string date na mysql datetime

  3. MySQLNumberTypeMapping' nepodporuje převody hodnot

  4. Jak funguje klauzule „in“ v orákulu