I MariaDB, EXCEPT
operatorn returnerar rader från den vänstra inmatningsfrågan som inte matas ut av den högra inmatningsfrågan.
Ett annat sätt att uttrycka det är att det returnerar alla rader från vänster SELECT
resultatuppsättning utom rader som är i höger SELECT
resultatuppsättning.
Syntax
Den officiella syntaxen ser ut så här:
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}]
Ovanstående inkluderar även INTERSECT
och UNION
operatorer i syntaxen, eftersom samma syntax gäller för dessa operatorer.
Från MariaDB 10.4.0 kan parenteser användas för att ange prioritet.
Exempel
Anta att vi har följande 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 använda EXCEPT
operatör för att returnera lärare som inte också är elever:
SELECT TeacherName FROM Teachers
EXCEPT
SELECT StudentName FROM Students;
Resultat:
+-------------+ | TeacherName | +-------------+ | Ben | | Cathy | +-------------+
Så vi får bara värden som visas i Teachers
tabell som inte också visas i Students
tabell.
Som standard returnerar den distinkta rader, så endast en rad returneras för Cathy
, även om det finns två lärare med det namnet. Vi kan ändra detta beteende – mer om detta senare.
Vi kan också byta det och sätta Students
tabellen till vänster och Teachers
till höger.
SELECT StudentName FROM Students
EXCEPT
SELECT TeacherName FROM Teachers;
Resultat:
+-------------+ | StudentName | +-------------+ | Faye | | Jet | | Spike | | Ein | +-------------+
Det är möjligt att få samma resultat utan att använda EXCEPT
operatör. Till exempel skulle vi kunna skriva om vårt första exempel till detta:
SELECT
DISTINCT TeacherName
FROM Teachers t
WHERE NOT EXISTS (SELECT StudentName FROM Students s
WHERE t.TeacherName = s.StudentName);
Resultat:
+-------------+ | TeacherName | +-------------+ | Ben | | Cathy | +-------------+
Kom ihåg, EXCEPT
operatören hjälper till att förenkla koden ganska avsevärt.
Inkludera dubbletter
Som standard är EXCEPT
operatorn tillämpar implicit en DISTINCT
drift. Med andra ord returnerar den endast distinkta värden som standard.
Före MariaDB 10.5.0, den implicita DISTINCT
var vårt enda alternativ – vi kunde inte ange ALL
. MariaDB 10.5.0 introducerade dock EXCEPT ALL
och EXCEPT DISTINCT
syntax.
Det betyder att vi nu kan göra frågor som denna:
SELECT TeacherName FROM Teachers
EXCEPT ALL
SELECT StudentName FROM Students;
Resultat:
+-------------+ | TeacherName | +-------------+ | Cathy | | Ben | | Cathy | | Bill | +-------------+
Den här gången fick vi fyra rader, istället för de två som vi fick i vårt första exempel.
Vi kan se att båda Cathys returnerades istället för bara en som i vårt första exempel.
Vad gäller Bill? Det finns två räkningar i Teachers
tabell, men bara en returneras här. Det beror förmodligen på att det finns en faktura i Students
tabell, vilket skulle utesluta en av räkningarna från våra resultat.
Och här är ett exempel som uttryckligen använder DISTINCT
operatör:
SELECT TeacherName FROM Teachers
EXCEPT DISTINCT
SELECT StudentName FROM Students;
Resultat:
+-------------+ | TeacherName | +-------------+ | Ben | | Cathy | +-------------+
Som förväntat får vi samma resultat som vi skulle få om vi skulle ta bort DISTINCT
operatör.
I MariaDB 10.6.1, MINUS
introducerades som en synonym för EXCEPT
. Därför kan vi använda MINUS
istället för EXCEPT
i MariaDB 10.6.1 och senare.