В MariaDB, MINUS операторът връща отделни редове от лявата входна заявка, които не са изведени от дясната входна заявка.
MINUS операторът беше въведен в MariaDB 10.6.1 като синоним на EXCEPT оператор за целите на съвместимостта с Oracle. Следователно можем да използваме MINUS и EXCEPT взаимозаменяемо (в MariaDB 10.6.1 и по-нови).
Открих обаче, че MINUS Операторът работи само когато моят sql_mode = "oracle" . Въпреки че това не е изрично споменато в документацията на MariaDB, то се подразбира в задачата за внедряване на MINUS оператор в MariaDB.
Примерни данни
Да предположим, че имаме следните таблици:
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 | +-----------+-------------+
Можем да използваме MINUS оператор, за да върне учители, които също не са ученици.
Задаване на sql_mode към Oracle
Преди да започнем да използваме MINUS оператор, нека зададем нашия sql_mode към oracle :
SET sql_mode = "oracle";
Добре, сега можем да продължим и да използваме MINUS оператор.
Пример за MINUS
SELECT TeacherName FROM Teachers
MINUS
SELECT StudentName FROM Students; Резултат:
+-------------+ | TeacherName | +-------------+ | Ben | | Cathy | +-------------+
Така че получаваме само стойности, които се появяват в Teachers таблица, която също не се показва в Students маса.
По подразбиране той връща отделни редове, така че само един ред се връща за Cathy , въпреки че има двама учители с това име. Можем да променим това поведение – повече за това по-късно.
Можем също да го превключим и да поставим Students таблица вляво и Teachers вдясно.
SELECT StudentName FROM Students
MINUS
SELECT TeacherName FROM Teachers; Резултат:
+-------------+ | StudentName | +-------------+ | Faye | | Jet | | Spike | | Ein | +-------------+
Възможно е да получите същия резултат, без да използвате MINUS (или EXCEPT ) оператор. Например, можем да пренапишем първия си пример на това:
SELECT
DISTINCT TeacherName
FROM Teachers t
WHERE NOT EXISTS (SELECT StudentName FROM Students s
WHERE t.TeacherName = s.StudentName); Резултат:
+-------------+ | TeacherName | +-------------+ | Ben | | Cathy | +-------------+
Включване на дубликати
По подразбиране MINUS оператор имплицитно прилага DISTINCT операция. С други думи, той връща само различни стойности по подразбиране. Но можем да посочим MINUS ALL за да включите дубликати в резултата:
SELECT TeacherName FROM Teachers
MINUS ALL
SELECT StudentName FROM Students; Резултат:
+-------------+ | TeacherName | +-------------+ | Cathy | | Ben | | Cathy | | Bill | +-------------+
Този път получихме четири реда, вместо двата, които получихме в първия ни пример.
Можем да видим, че и двете Кати бяха върнати вместо само една, както в първия ни пример.
Колкото до Бил? Има два законопроекта в Teachers таблица, но тук се връща само една. Това вероятно е защото има един законопроект в Students таблица, която би изключила един от законопроектите от нашите резултати.
И ето пример, който изрично използва DISTINCT оператор:
SELECT TeacherName FROM Teachers
MINUS DISTINCT
SELECT StudentName FROM Students; Резултат:
+-------------+ | TeacherName | +-------------+ | Ben | | Cathy | +-------------+
Както се очакваше, получаваме същия резултат, който бихме получили, ако премахнем DISTINCT оператор.
Не сте в режим на Oracle?
Ето какво се случва, когато се опитаме да използваме MINUS когато не е в режим на Oracle.
Нека нулираме нашия sql_mode до настройката по подразбиране:
SET sql_mode = default;
Сега нека опитаме да използваме MINUS оператор отново:
SELECT TeacherName FROM Teachers
MINUS
SELECT StudentName FROM Students; Резултат:
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'SELECT StudentName FROM Students' at line 3