Урок 3: Joins и Отношения — Давайте Заставим Ваши Таблицы Общаться!


Lesson3

Урок 3: Joins и Отношения — Давайте Заставим Ваши Таблицы Общаться!

Привет снова, отважный рыцарь данных! Теперь, когда ты научился создавать и управлять своими таблицами, пора дать им немного… э-э, общения. Ведь таблицы не должны просто сидеть в своих замках, глядя друг на друга через ров. Нет, они должны разговаривать! Сегодня мы погрузимся в мир Joins и Отношений — это как вечеринка для таблиц, где каждая из них выбрала свою пару для танцев!

Что такое Join?

Проще говоря, Join — это способ сказать PostgreSQL: «Эй, подружи эти две таблицы!» Соединения позволяют объединять данные из двух или более таблиц на основе связанной колонки. Представьте, что вы организовываете ужин, где у каждого стола есть уникальный список гостей, но все они как-то связаны (например, любовью к борщу или умением готовить пельмени).

Типы соединений: Кто с кем дружит?

Существует несколько видов соединений, каждый со своим характером. Давайте посмотрим, кто из них готов на дружеский разговор:

  1. INNER JOIN: Встреча только для тех, у кого есть что-то общее.
  2. LEFT JOIN: Все из левой таблицы заходят, а из правой мы пригласим только тех, кто соответствует.
  3. RIGHT JOIN: Противоположность LEFT JOIN — правый стол главный, а левый может присоединиться, если повезет.
  4. FULL OUTER JOIN: Все приглашаются, даже если они вообще не знают, что это за вечеринка!

Давайте посмотрим на них в действии!

1. INNER JOIN: Только для избранных

INNER JOIN возвращает только те строки, которые имеют совпадения в обеих таблицах. Представьте, у вас есть таблица rycari и таблица missii. Таблица rycari перечисляет всех рыцарей, а таблица missii — миссии, на которые они записались:

CREATE TABLE rycari (
    id SERIAL PRIMARY KEY,
    imya VARCHAR(100),
    korolevstvo VARCHAR(50)
);

CREATE TABLE missii (
    id SERIAL PRIMARY KEY,
    rycar_id INT,
    nazvanie_missii VARCHAR(100)
);

Теперь давайте узнаем, какие рыцари приняли миссию:

SELECT rycari.imya, missii.nazvanie_missii
FROM rycari
INNER JOIN missii
ON rycari.id = missii.rycar_id;

Этот запрос вернет список всех рыцарей, которые в данный момент на миссии. Если рыцарь просто сидит в Камелоте, пуская мыльные пузыри, его тут не будет. (Прости, сэр Ланселот, найди себе какое-нибудь приключение!)

2. LEFT JOIN: Гостеприимный Хозяин

LEFT JOIN возвращает все строки из левой таблицы (rycari), а также соответствующие строки из правой таблицы (missii). Если совпадений нет, то для правой таблицы значение будет NULL. Это как пригласить всех рыцарей на вечеринку и проверить, кто из них действительно занят делом.

SELECT rycari.imya, missii.nazvanie_missii
FROM rycari
LEFT JOIN missii
ON rycari.id = missii.rycar_id;

Теперь, даже если рыцарь просто сидит и начищает свою кольчугу, он все равно появится в списке — но с NULL вместо миссии. Тоскливое зрелище, правда?

3. RIGHT JOIN: Обратный Подход

RIGHT JOIN делает наоборот — возвращает все строки из правой таблицы (missii) и соответствующие строки из левой таблицы (rycari). Это как спросить: «Какие миссии доступны и кто готов их принять?»

SELECT rycari.imya, missii.nazvanie_missii
FROM rycari
RIGHT JOIN missii
ON rycari.id = missii.rycar_id;

Это покажет все миссии, даже если некоторые из них просто сидят и ждут, пока какой-нибудь рыцарь отважится на подвиг.

4. FULL OUTER JOIN: Вечеринка для Всех!

FULL OUTER JOIN возвращает все строки, если есть совпадения в любой из таблиц. Если совпадений нет, вы получите NULL. Это как пригласить всех на шашлыки, даже если никто не знает, кто вообще приносил мясо!

SELECT rycari.imya, missii.nazvanie_missii
FROM rycari
FULL OUTER JOIN missii
ON rycari.id = missii.rycar_id;

Этот запрос покажет всех рыцарей и все миссии, независимо от того, связаны ли они как-то друг с другом. Это как огромная ярмарка, где каждый продает, даже если никто ничего не покупает.

Построение Отношений: Первичные и Внешние Ключи

Итак, как сказать PostgreSQL, что rycar_id в таблице missii связан с колонкой id в таблице rycari? Здесь начинается магия отношений.

  1. Первичный Ключ (Primary Key): Это как паспорт рыцаря. Уникально идентифицирует каждую строку в таблице. В нашем случае, rycari.id — это первичный ключ.
  2. Внешний Ключ (Foreign Key): Это как пропуск на турнир. Он ссылается на первичный ключ в другой таблице. Здесь missii.rycar_id — это внешний ключ, указывающий на rycari.id.

Официальное Добавление Внешнего Ключа

Давайте сделаем это официально, добавив ограничение внешнего ключа в нашу таблицу missii:

ALTER TABLE missii
ADD CONSTRAINT fk_rycar
FOREIGN KEY (rycar_id)
REFERENCES rycari(id);

Теперь PostgreSQL знает, что missii.rycar_id должен соответствовать rycari.id. Если вы попытаетесь создать миссию для несуществующего рыцаря, PostgreSQL остановит вас быстрее, чем огнедышащий дракон!

Все В Месте: Небольшой Сценарий

Вот небольшой сценарий, чтобы увидеть все эти joins в действии:

CREATE TABLE rycari (
    id SERIAL PRIMARY KEY,
    imya VARCHAR(100),
    korolevstvo VARCHAR(50)
);

CREATE TABLE missii (
    id SERIAL PRIMARY KEY,
    rycar_id INT,
    nazvanie_missii VARCHAR(100),
    FOREIGN KEY (rycar_id) REFERENCES rycari(id)
);

INSERT INTO rycari (imya, korolevstvo)
VALUES ('Сэр Ланселот', 'Камелот'),
       ('Сэр Галахад', 'Камелот'),
       ('Король Артур', 'Камелот');

INSERT INTO missii (rycar_id, nazvanie_missii)
VALUES (1, 'Искать Грааль'),
       (2, 'Победить Черного Рыцаря');

Попробуйте выполнить этот сценарий в вашем PostgreSQL, и наблюдайте, как рыцари и миссии начнут взаимодействовать, как на светском приеме!

Что Мы Сегодня Узнали?

Сегодня мы рассмотрели:

  • INNER JOIN: Возвращает строки из обеих таблиц, если есть совпадение.
  • LEFT JOIN: Возвращает все строки из левой таблицы, даже если справа пусто.
  • RIGHT JOIN: Возвращает все строки из правой таблицы.
  • FULL OUTER JOIN: Все приглашены, даже если они не знают, почему.

Пусть ваши Joins всегда будут быстрыми, а результаты — безупречными!