← К оглавлению занятия

Занятие 27. Практикум 7

📁 Блок: SQL / MySQL / Подзапросы и CTE ⏱️ Время изучения: ~90 мин 🎯 Сложность: Практикум
#join #where #null #in #select #as #create

⚡ Кратко: типичные ошибки

  • INNER JOIN вместо LEFT JOIN для поиска отсутствующих связей.
  • Забытые скобки вокруг определения CTE.
  • Неочищенные временные таблицы.

🐛 Типичные ошибки и исправления

Ошибка 1. INNER JOIN для поиска сотрудников без привилегий

Неправильно:

SELECT e.first_name, e.last_name
FROM employees AS e
JOIN employee_privileges AS ep ON e.id = ep.employee_id
WHERE ep.employee_id IS NULL;

Почему плохо: INNER JOIN отбрасывает всех сотрудников, у которых нет связи с employee_privileges. Условие IS NULL после него никогда не выполнится.

Правильно:

SELECT e.first_name, e.last_name
FROM employees AS e
LEFT JOIN employee_privileges AS ep ON e.id = ep.employee_id
WHERE ep.employee_id IS NULL;

Ошибка 2. Пропуск скобок в CTE

Неправильно:

WITH selected_employees AS
    SELECT id FROM employees WHERE first_name LIKE '%e%'
SELECT * FROM orders WHERE employee_id IN (SELECT id FROM selected_employees);

Правильно:

WITH selected_employees AS (
    SELECT id FROM employees WHERE first_name LIKE '%e%'
)
SELECT * FROM orders WHERE employee_id IN (SELECT id FROM selected_employees);

Ошибка 3. Неудалённые временные таблицы

После работы с CREATE TEMPORARY TABLE желательно вызывать DROP TEMPORARY TABLE IF EXISTS. Иначе в активной сессии могут накопиться таблицы и при повторном запуске возникнет ошибка Table already exists.

Ошибка 4. Путаница в логике OR

В задании 2 условие «имя содержит 'e' ИЛИ job_title = 'Sales Representative'» относится к сотрудникам. Если поставить скобки неверно, условие может примениться и к заказам:

-- Неправильно: OR связывает ship_city и job_title
WHERE ship_city = 'Las Vegas' OR job_title = 'Sales Representative'

Правильно выносить фильтр по сотрудникам в подзапрос или CTE, а затем накладывать условие на заказы.