Модуль 10

JOINs Explained Visually

Ось готовий урок у стилі CS50. Уяви, що ми зараз в Sanders Theatre, я ходжу сценою, жестикулюю і звертаюся особисто до тебе. Поїхали!


🎓 CS50: JOINs Explained Visually (Візуалізація з’єднань SQL)

Привіт, друзі! Радий бачити вас.

Сьогодні ми поговоримо про одну з найпотужніших концепцій у роботі з даними. Це те, що перетворює прості таблиці на справжню інформаційну систему. Ми говоримо про JOINs.


1. 🔥 Вступ: Чому ми не можемо просто жити з однією таблицею?

Уявіть, що ви відкрили власний інтернет-магазин кросівок. У вас є Excel-файл, куди ви записуєте кожне замовлення.

Виглядає це приблизно так:

ID Замовлення Ім'я Клієнта Email Клієнта Адреса Клієнта Товар Ціна
1 Тарас taras@gmail.com Київ, Хрещатик 1 Nike Air 3000
2 Тарас taras@gmail.com Київ, Хрещатик 1 Adidas 2500
3 Олена elena@ukr.net Львів, Площа Ринок Puma 2000

Бачите проблему? Подивіться на Тараса. Ми двічі записали його email та адресу. А якщо Тарас зробить 100 замовлень? А якщо він переїде, і нам доведеться змінювати його адресу в 100 рядках? Це пекло. Це неефективно. Це шлях до помилок.

Риторичне питання: Хіба не було б логічніше зберігати клієнтів в одному місці, а замовлення — в іншому?

Звісно! Ми розділяємо дані на дві таблиці: users (користувачі) та orders (замовлення). Але тут виникає нова проблема: як тепер дізнатися, хто саме замовив ці Nike Air?

Нам потрібен "клей". Нам потрібен спосіб сказати базі даних: "Гей, візьми цей рядок з таблиці замовлень і знайди відповідний рядок у таблиці користувачів".

Цей клей — це JOIN. Без нього ваші дані — це просто розрізнені шматки пазла.


2. 🧠 Теоретична база: Магія кіл Ейлера

Не лякайтеся слова "теорія". Давайте уявимо це візуально.

У нас є дві множини (уявіть два кола): 1. 🔵 Коло А (Users): Всі ваші зареєстровані користувачі. 2. 🟢 Коло Б (Orders): Всі зроблені замовлення.

Як це працює "під капотом"? База даних бере рядок з однієї таблиці і сканує іншу таблицю, шукаючи збіг за унікальним ідентифікатором (зазвичай це id користувача).

🔑 Ключові поняття, які треба знати:

  1. Primary Key (PK): Унікальний паспорт користувача (наприклад, user_id = 1).
  2. Foreign Key (FK): Посилання на цей паспорт в іншій таблиці (у замовленні написано user_id = 1).
  3. JOIN: Команда "З’єднай ці рядки, якщо ключі співпадають".

Типи з’єднань (Інтуїтивно):

  • INNER JOIN (Внутрішнє з’єднання):

    • Аналогія: Ви гукаєте: "Хто зробив замовлення — крок уперед!".
    • Вийдуть тільки ті користувачі, які мають замовлення.
    • Ті, хто просто зареєструвався, але нічого не купив — залишаться на місці.
    • Результат: Перетин двох кіл (тільки спільне).
  • LEFT JOIN (Ліве з’єднання):

    • Аналогія: Ви — директор відділу маркетингу. Вам потрібен список всіх клієнтів.
    • Ви кажете: "Всі клієнти, шикуйсь! Якщо у вас є замовлення — тримайте їх у руках. Якщо немає — стійте з порожніми руками".
    • Результат: Все ліве коло (клієнти) + відповідні дані з правого (замовлення), якщо вони є. Якщо немає — там буде пустота (NULL).

3. 🧪 Приклади: Від простого до реального

Давайте подивимось на дані.

Таблиця users: | id | name | | :--- | :--- | | 1 | Тарас | | 2 | Олена | | 3 | Іван (нічого не купив) |

Таблиця orders: | id | user_id | product | | :--- | :--- | :--- | | 101 | 1 | Nike Air | | 102 | 1 | Adidas | | 103 | 2 | Puma |

Приклад 1: INNER JOIN (Сувора реальність)

Ми хочемо отримати чек: Ім'я + Товар.

SELECT users.name, orders.product
FROM users
INNER JOIN orders ON users.id = orders.user_id;

Питання до вас: Чи побачимо ми Івана у цьому списку? ... Відповідь: Ні! INNER JOIN відкидає все, що не має пари. Іван не зробив замовлення, тому для бази даних у цьому запиті його не існує.

Результат: * Тарас — Nike Air * Тарас — Adidas * Олена — Puma


Приклад 2: LEFT JOIN (Інклюзивність)

Тепер ми хочемо надіслати розсилку всім користувачам. Нам потрібні всі, навіть "ліниві".

SELECT users.name, orders.product
FROM users
LEFT JOIN orders ON users.id = orders.user_id;

Що ми очікуємо? Ми побачимо всіх. Але що буде навпроти імені Івана в колонці товару?

Результат: * Тарас — Nike Air * Тарас — Adidas * Олена — Puma * Іван — NULL (пустота)

Чому це важливо? Тому що тепер ми можемо знайти всіх, хто має NULL, і надіслати їм промокод: "Ей, Іване, ти давно з нами, але нічого не купив!"


4. 🛠 Практична частина

Час "забруднити руки". Ось ваші завдання. Уявіть, що ви працюєте з базою даних бібліотеки (readers та books_taken).

  1. 🔹 Розігрів: Напишіть INNER JOIN, щоб показати імена читачів і назви книг, які вони взяли.
  2. 🔹 Пошук боржників (NULL): Використовуйте LEFT JOIN, щоб знайти читачів, які зареєструвалися, але ще не взяли жодної книги. (Підказка: шукайте, де books_taken.id IS NULL).
  3. 🔹 Виправлення помилки: Студент написав: sql SELECT name, title FROM readers JOIN books_taken ON id = reader_id; База видає помилку: Ambiguous column name: id. Чому? Як це виправити?
  4. 🔹 Міні-кейс: У нас з'явилася третя таблиця authors. Книга має author_id. Як з'єднати всі три таблиці, щоб отримати: Ім'я читача — Назва книги — Ім'я автора? (Підказка: можна робити декілька JOIN поспіль).
  5. 🔹 А що, якщо... Ви використали RIGHT JOIN. Що зміниться? (Подумайте, чи можуть існувати взяті книги без читача?).

5. 💡 Мислення як у розробника

Як відрізнити новачка від профі в темі JOIN?

1. Аліаси (Псевдоніми) — це ваші друзі. Новачок пише: users.name, orders.product. Профі пише:

SELECT u.name, o.product
FROM users AS u
JOIN orders AS o ON u.id = o.user_id;

Це економить час і робить код читабельним.

2. Страх перед NULL. Новачки бояться NULL. Досвідчені розробники використовують NULL як інструмент. Якщо після LEFT JOIN ви бачите NULL — це не помилка, це відсутність зв'язку, і це цінна інформація для аналітики.

3. Проблема "Вибуху даних". Обережно! Якщо в одній таблиці 100 записів, і в іншій 100, і ви випадково зробите з'єднання без умови ON (це називається CROSS JOIN), ви отримаєте 10 000 рядків. Це покладе ваш сервер. Завжди перевіряйте умову ON.


6. 🧩 Підсумок

Отже, що ми сьогодні зробили? 1. Зрозуміли, що зберігати все в одній таблиці — це зло. 2. Навчилися "склеювати" таблиці назад за допомогою JOIN. 3. Розібралися, коли використовувати INNER (тільки збіги), а коли LEFT (всі з лівої таблиці).

Що ви тепер вмієте? Ви вмієте поєднувати сутності. Ви можете взяти клієнта і побачити його історію. Ви можете взяти товар і побачити, хто його купував. Ви перейшли від простого зберігання даних до побудови зв'язків.

🕵️‍♀️ Тизер наступного уроку: Окей, ми з'єднали таблиці і побачили, що Тарас купив 2 товари. А як нам одним запитом дізнатися, скільки всього грошей витратив Тарас? Ми не хочемо бачити список, ми хочемо суму. Наступного разу ми поговоримо про Агрегацію та GROUP BY.

А на сьогодні це все! Це був CS50. Щасти!