В MariaDB, EXCEPT
операторът връща редове от лявата входна заявка, които не се извеждат от дясната входна заявка.
Друг начин да го поставите е, че връща всички редове отляво SELECT
набор от резултати освен редове, които са в дясно SELECT
набор от резултати.
Синтаксис
Официалният синтаксис е така:
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}]
Горното включва също INTERSECT
и UNION
оператори в синтаксиса, тъй като същият синтаксис се прилага за тези оператори.
От MariaDB 10.4.0, скоби могат да се използват за определяне на приоритет.
Пример
Да предположим, че имаме следните таблици:
SELECT * FROM Teachers;
SELECT * FROM Students;
Резултат:
+-----------+-------------+ | 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 | +-----------+-------------+
Можем да използваме EXCEPT
оператор, за да върне учители, които също не са студенти:
SELECT TeacherName FROM Teachers
EXCEPT
SELECT StudentName FROM Students;
Резултат:
+-------------+ | TeacherName | +-------------+ | Ben | | Cathy | +-------------+
Така че получаваме само стойности, които се появяват в Teachers
таблица, която също не се показва в Students
маса.
По подразбиране той връща отделни редове, така че само един ред се връща за Cathy
, въпреки че има двама учители с това име. Можем да променим това поведение – повече за това по-късно.
Можем също да го превключим и да поставим Students
таблица вляво и Teachers
вдясно.
SELECT StudentName FROM Students
EXCEPT
SELECT TeacherName FROM Teachers;
Резултат:
+-------------+ | StudentName | +-------------+ | Faye | | Jet | | Spike | | Ein | +-------------+
Възможно е да получите същия резултат, без да използвате EXCEPT
оператор. Например, можем да пренапишем първия си пример на това:
SELECT
DISTINCT TeacherName
FROM Teachers t
WHERE NOT EXISTS (SELECT StudentName FROM Students s
WHERE t.TeacherName = s.StudentName);
Резултат:
+-------------+ | TeacherName | +-------------+ | Ben | | Cathy | +-------------+
Имайте предвид, EXCEPT
операторът помага за значително опростяване на кода.
Включване на дубликати
По подразбиране EXCEPT
оператор имплицитно прилага DISTINCT
операция. С други думи, той връща само различни стойности по подразбиране.
Преди MariaDB 10.5.0 имплицитният DISTINCT
беше единствената ни опция – не успяхме да посочим ALL
. Въпреки това, MariaDB 10.5.0 въведе EXCEPT ALL
и EXCEPT DISTINCT
синтаксис.
Това означава, че вече можем да правим заявки като това:
SELECT TeacherName FROM Teachers
EXCEPT ALL
SELECT StudentName FROM Students;
Резултат:
+-------------+ | TeacherName | +-------------+ | Cathy | | Ben | | Cathy | | Bill | +-------------+
Този път получихме четири реда, вместо двата, които получихме в първия ни пример.
Можем да видим, че и двете Кати бяха върнати вместо само една, както в първия ни пример.
Колкото до Бил? Има два законопроекта в Teachers
таблица, но тук се връща само една. Това вероятно е защото има един законопроект в Students
таблица, която би изключила един от законопроектите от нашите резултати.
И ето пример, който изрично използва DISTINCT
оператор:
SELECT TeacherName FROM Teachers
EXCEPT DISTINCT
SELECT StudentName FROM Students;
Резултат:
+-------------+ | TeacherName | +-------------+ | Ben | | Cathy | +-------------+
Както се очакваше, получаваме същия резултат, който бихме получили, ако премахнем DISTINCT
оператор.
В MariaDB 10.6.1, MINUS
беше въведен като синоним на EXCEPT
. Следователно можем да използваме MINUS
вместо EXCEPT
в MariaDB 10.6.1 и по-нови версии.