V PostgreSQL EXCEPT
Operátor vrací řádky, které jsou vráceny levým vstupním dotazem, které nejsou vráceny pravým vstupním dotazem. To lze také označit jako rozdíl mezi dvěma dotazy.
Syntaxe
Syntaxe vypadá takto:
query1 EXCEPT [ALL] query2
Duplikáty jsou eliminovány, pokud EXCEPT ALL
se používá.
Příklad
Předpokládejme, že máme následující tabulky:
SELECT * FROM Teachers;
SELECT * FROM Students;
Výsledek:
teacherid | teachername -----------+------------- 1 | Warren 2 | Ben 3 | Cathy 4 | Cathy 5 | Bill 6 | Bill studentid | studentname -----------+------------- 1 | Faye 2 | Jet 3 | Spike 4 | Ein 5 | Warren 6 | Bill
Můžeme použít EXCEPT
operátor vrátit učitele, kteří nejsou zároveň studenty:
SELECT TeacherName FROM Teachers
EXCEPT
SELECT StudentName FROM Students;
Výsledek:
teachername ------------- Cathy Ben
Získáváme tedy pouze hodnoty, které se objevují v Teachers
tabulka, která se také neobjevuje v Students
stůl.
Ve výchozím nastavení EXCEPT
operátor vrací odlišné řádky. V našem příkladu je tedy vrácen pouze jeden řádek pro Cathy
, i když jsou dva učitelé s tímto jménem.
Výše uvedený příklad je ekvivalentem následujícího dotazu:
SELECT TeacherName FROM Teachers
EXCEPT DISTINCT
SELECT StudentName FROM Students;
Výsledek:
teachername ------------- Cathy Ben
Toto je stejný výsledek, jaký jsme dostali, když neexistoval žádný explicitní DISTINCT
klíčové slovo. Můžeme zahrnout duplikáty pomocí ALL
klíčové slovo (více o tom později).
Můžeme získat různé výsledky podle toho, která tabulka je vlevo a která vpravo. Zde je příklad, který uvádí Students
tabulka vlevo a Teachers
vpravo:
SELECT StudentName FROM Students
EXCEPT
SELECT TeacherName FROM Teachers;
Výsledek:
studentname ------------- Faye Jet Spike Ein
Tentokrát dostáváme studenty, kteří nejsou zároveň učiteli.
Zahrnout duplikáty
Ve výchozím nastavení EXCEPT
operátor implicitně aplikuje DISTINCT
úkon. Jinými slovy, ve výchozím nastavení vrací pouze odlišné hodnoty.
Můžeme zahrnout ALL
klíčové slovo, abychom do našeho výsledku zahrnuli duplikáty:
SELECT TeacherName FROM Teachers
EXCEPT ALL
SELECT StudentName FROM Students;
Výsledek:
teachername ------------- Cathy Cathy Bill Ben
Tentokrát jsme dostali čtyři řádky místo dvou, které jsme dostali v našem prvním příkladu.
Můžeme vidět, že obě Cathy byly vráceny místo jedné, jako v našem prvním příkladu.
Co se týče Billa? V Teachers
jsou dva návrhy zákonů stůl, ale vrací se sem jen jeden. Je to pravděpodobně proto, že v Students
je jeden účet tabulky, což by vyřadilo jeden z účtů z našich výsledků.
Alternativa
Je možné získat stejný výsledek bez použití EXCEPT
operátor. Například bychom mohli přepsat náš první příklad na toto:
SELECT
DISTINCT TeacherName
FROM Teachers t
WHERE NOT EXISTS (SELECT StudentName FROM Students s
WHERE t.TeacherName = s.StudentName);
Výsledek:
teachername ------------- Cathy Ben