JavaRush/Java курси/Модуль 4. Робота з БД/Вибірка даних із кількох таблиць

Вибірка даних із кількох таблиць

Відкрита

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.

1
Задача
Модуль 4. Робота з БД,  3 рівень0 лекція
Недоступна
Знайти в різних таблицях
task0301
1
Задача
Модуль 4. Робота з БД,  3 рівень0 лекція
Недоступна
Мені наснилося небо Лондона
task0302
1
Задача
Модуль 4. Робота з БД,  3 рівень0 лекція
Недоступна
Коли ім'я та назва рівні
task0303
1
Задача
Модуль 4. Робота з БД,  3 рівень0 лекція
Недоступна
Різні колонки, різні таблиці
task0304
1
Задача
Модуль 4. Робота з БД,  3 рівень0 лекція
Недоступна
Робота з аліасами таблиць
task0305
1
Задача
Модуль 4. Робота з БД,  3 рівень0 лекція
Недоступна
Де ж ви є, красуні
task0306
1
Задача
Модуль 4. Робота з БД,  3 рівень0 лекція
Недоступна
Фільтруємо за id
task0307
1
Задача
Модуль 4. Робота з БД,  3 рівень0 лекція
Недоступна
Знайди Халка
task0308
1
Задача
Модуль 4. Робота з БД,  3 рівень0 лекція
Недоступна
Сортуємо за локаціями
task0309
Коментарі
  • популярні
  • нові
  • старі
Щоб залишити коментар, потрібно ввійти в систему
Для цієї сторінки немає коментарів.