1. Залежна таблиця

Тепер трохи ускладнимо наші запити. Додамо до нашої бази даних нову таблицю task із завданнями для наших співробітників. І подивимося, які в ній записи:


SELECT * FROM task  

Результат такого запиту:

id emploee_id name deadline
1 1 Виправити багу на фронтенді 2022-06-01
2 2 Виправити багу на бекенді 2022-06-15
3 5 Купити каву 2022-07-01
4 5 Купити каву 2022-08-01
5 5 Купить каву 2022-09-01
6 (NULL) Прибрати офіс (NULL)
7 4 Насолоджуватися життям (NULL)
8 6 Насолоджуватися життям (NULL)

У цій таблиці є лише 4 колонки:

  • id — унікальний номер завдання (та рядки у таблиці);
  • employee_id — ID співробітника з таблиці employee, на якого призначено завдання;
  • name — назва та опис завдання;
  • deadline — час, до якого потрібно виконати завдання.

Зверни увагу на кілька нюансів. Завдання N6 не має employee_id: ми не маємо прибиральниці. Завдання є, а виконавця немає. Таке буває.

Також завдання 6-9 не мають встановленого дедлайну. Таке буває, коли завдання має виконуватися регулярно і безперервно. Наприклад, офіс потрібно прибирати щодня, та й насолоджуватися життям теж потрібно щодня :)

Якщо в одній таблиці використовуються ID з іншої таблиці, то така таблиця називається залежною.

2. Запит до кількох таблиць

Ось ми бачимо в таблиці task, що є два завдання "Насолоджуватися життям". Як нам дізнатися, хто саме ці щасливчики?

Для цього SQL можна виконати запит відразу до двох таблиць. Взагалі в SQL можна виконувати запит до будь-якої кількості таблиць одночасно. Загальний формат такого запиту:

SELECT колонки 
FROM таблиця1, таблиця2, таблицяN

Важливо! Якщо ти напишеш запит до кількох таблиць одночасно, в результаті отримаєш так званий декартовий твір рядків таблиць. До кожного рядка з першої таблиці буде приклеєно кожен рядок з другої таблиці і так далі.

Тобто, якщо в першій таблиці у тебе 5 рядків, а в другій — 10, загалом у тебе буде 50 рядків. На мові Java цей запит виглядав би приблизно так:


for (String row1 : table1)
{
for (String row2 : table2)
   {
  System.out.println(row1 + row2);
   }
}

Давай напишемо наш запит одразу до двох таблиць і подивимося, що вийде:


SELECT * FROM employee, task

Ось результат такого запиту:

id name occupation salary age id emploee_id name deadline
1 Шевченко Ігор Програміст 100000 25 1 1 Виправити багу на фронтенді 2022-06-01
2 Коваленко Максим Програміст 80000 23 1 1 Виправити багу на фронтенді 2022-06-01
3 Шевченко Данило Тестувальник 40000 30 1 1 Виправити багу на фронтенді 2022-06-01
4 Мельник Степан Директор 200000 35 1 1 Виправити багу на фронтенді 2022-06-01
5 Кірієнко Анастасія Офіс-менеджер 40000 25 1 1 Виправити багу на фронтенді 2022-06-01
6 Пончик кіт 1000 3 1 1 Виправити багу на фронтенді 2022-06-01
1 Шевченко Ігор Програміст 100000 25 2 2 Виправити багу на бекенді 2022-06-15
2 Коваленко Максим Програміст 80000 23 2 2 Виправити багу на бекенді 2022-06-15
3 Шевченко Данило Тестувальник 40000 30 2 2 Виправити багу на бекенді 2022-06-15
4 Мельник Степан Директор 200000 35 2 2 Виправити багу на бекенді 2022-06-15
5 Кірієнко Анастасія Офіс-менеджер 40000 25 2 2 Виправити багу на бекенді 2022-06-15

Загалом рядків результату у нас 48, але тут я навів лише 11. Інакше просто місця не вистачить.

Зверни увагу на три речі:

  • Колонки з однаковими іменами: id. Це id із таблиці employee та id із таблиці task.
  • Рядки кожної таблиці повторюються. У лівій колонці після ID 6 знову йде ID = 1.
  • У нас є безглузді рядки, коли, наприклад, id (з таблиці employee) дорівнює 6, і в тому ж рядку employee_id дорівнює 1.

3. Забираємо безглузді рядки

У нашій результуючій таблиці, яка є декартовим твором всіх рядків двох таблиць employee та task дуже багато рядків.

Логічно, що якщо у рядку employee_id дорівнює 3, то вона повинна приклеюватися лише до рядка з таблиці employee, де id дорівнює 3. Давай спробуємо виправити це непорозуміння за допомогою WHERE.

Напишемо такий запит:

SELECT * FROM employee, task
WHERE emploee.id = task.emploee_id 

І результат такого запиту:

id name occupation salary age id emploee_id name deadline
1 Шевченко Ігор Програміст 100000 25 1 1 Виправити багу на фронтенді 2022-06-01
2 Коваленко Максим Програміст 80000 23 2 2 Виправити багу на бекенді 2022-06-15
4 Мельник Степан Директор 200000 35 7 4 Насолоджуватися життям (NULL)
5 Кірієнко Анастасія Офіс-менеджер 40000 25 3 5 Купити каву 2022-07-01
5 Кірієнко Анастасія Офіс-менеджер 40000 25 4 5 Купити каву 2022-08-01
5 Кірієнко Анастасія Офіс-менеджер 40000 25 5 5 Купить каву 2022-09-01
6 Пончик кіт 1000 3 8 6 Насолоджуватися життям (NULL)

Хороша новина — у нас зникли безглузді рядки: id з першої колонки завжди employee_id.

Погана новина — зникли завдання, які ні на кого не призначені, такі як прибирання офісу. Їх employee_id дорівнював NULL, тому вони були відкинуті після виконання WHERE.