I MariaDB er EXCEPT
operatør returnerer rækker fra den venstre inputforespørgsel, som ikke udlæses af den højre inputforespørgsel.
En anden måde at sætte det på er, at det returnerer alle rækker fra venstre SELECT
resultatsæt undtagen rækker, der er i højre SELECT
resultatsæt.
Syntaks
Den officielle syntaks lyder sådan her:
SELECT ...
(INTERSECT [ALL | DISTINCT] | EXCEPT [ALL | DISTINCT] | UNION [ALL | DISTINCT]) SELECT ...
[(INTERSECT [ALL | DISTINCT] | EXCEPT [ALL | DISTINCT] | UNION [ALL | DISTINCT]) SELECT ...]
[ORDER BY [column [, column ...]]]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
Ovenstående inkluderer også INTERSECT
og UNION
operatorer i syntaksen, da den samme syntaks gælder for disse operatorer.
Fra MariaDB 10.4.0 kan parenteser bruges til at angive forrang.
Eksempel
Antag, at vi har følgende tabeller:
SELECT * FROM Teachers;
SELECT * FROM Students;
Resultat:
+-----------+-------------+ | 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 | +-----------+-------------+
Vi kan bruge EXCEPT
operatør for at returnere lærere, der ikke også er studerende:
SELECT TeacherName FROM Teachers
EXCEPT
SELECT StudentName FROM Students;
Resultat:
+-------------+ | TeacherName | +-------------+ | Ben | | Cathy | +-------------+
Så vi får kun værdier, der vises i Teachers
tabel, der ikke også vises i Students
bord.
Som standard returnerer den distinkte rækker, så kun én række returneres for Cathy
, selvom der er to lærere med det navn. Vi kan ændre denne adfærd - mere om dette senere.
Vi kan også skifte det rundt og sætte Students
tabel til venstre og Teachers
til højre.
SELECT StudentName FROM Students
EXCEPT
SELECT TeacherName FROM Teachers;
Resultat:
+-------------+ | StudentName | +-------------+ | Faye | | Jet | | Spike | | Ein | +-------------+
Det er muligt at få det samme resultat uden at bruge EXCEPT
operatør. For eksempel kunne vi omskrive vores første eksempel til dette:
SELECT
DISTINCT TeacherName
FROM Teachers t
WHERE NOT EXISTS (SELECT StudentName FROM Students s
WHERE t.TeacherName = s.StudentName);
Resultat:
+-------------+ | TeacherName | +-------------+ | Ben | | Cathy | +-------------+
Husk EXCEPT
operatør hjælper med at forenkle koden ganske betydeligt.
Medtag dubletter
Som standard er EXCEPT
operatør anvender implicit en DISTINCT
operation. Med andre ord returnerer det kun distinkte værdier som standard.
Før MariaDB 10.5.0, den implicitte DISTINCT
var vores eneste mulighed – vi var ikke i stand til at angive ALL
. MariaDB 10.5.0 introducerede dog EXCEPT ALL
og EXCEPT DISTINCT
syntaks.
Det betyder, at vi nu kan lave forespørgsler som denne:
SELECT TeacherName FROM Teachers
EXCEPT ALL
SELECT StudentName FROM Students;
Resultat:
+-------------+ | TeacherName | +-------------+ | Cathy | | Ben | | Cathy | | Bill | +-------------+
Denne gang fik vi fire rækker i stedet for de to, som vi fik i vores første eksempel.
Vi kan se, at begge Cathys blev returneret i stedet for blot én som i vores første eksempel.
Hvad angår Bill? Der er to regninger i Teachers
bord, men kun én returneres her. Det er sandsynligvis, fordi der er én regning i Students
tabel, hvilket ville udelukke et af lovforslagene fra vores resultater.
Og her er et eksempel, der eksplicit bruger DISTINCT
operatør:
SELECT TeacherName FROM Teachers
EXCEPT DISTINCT
SELECT StudentName FROM Students;
Resultat:
+-------------+ | TeacherName | +-------------+ | Ben | | Cathy | +-------------+
Som forventet får vi det samme resultat, som vi ville få, hvis vi skulle fjerne DISTINCT
operatør.
I MariaDB 10.6.1, MINUS
blev introduceret som et synonym for EXCEPT
. Derfor kan vi bruge MINUS
i stedet for EXCEPT
i MariaDB 10.6.1 og senere.