Урок 3: Joins и Отношения — Давайте Заставим Ваши Таблицы Общаться!
Привет снова, отважный рыцарь данных! Теперь, когда ты научился создавать и управлять своими таблицами, пора дать им немного… э-э, общения. Ведь таблицы не должны просто сидеть в своих замках, глядя друг на друга через ров. Нет, они должны разговаривать! Сегодня мы погрузимся в мир Joins и Отношений — это как вечеринка для таблиц, где каждая из них выбрала свою пару для танцев!
Что такое Join?
Проще говоря, Join — это способ сказать PostgreSQL: «Эй, подружи эти две таблицы!» Соединения позволяют объединять данные из двух или более таблиц на основе связанной колонки. Представьте, что вы организовываете ужин, где у каждого стола есть уникальный список гостей, но все они как-то связаны (например, любовью к борщу или умением готовить пельмени).
Типы соединений: Кто с кем дружит?
Существует несколько видов соединений, каждый со своим характером. Давайте посмотрим, кто из них готов на дружеский разговор:
- INNER JOIN: Встреча только для тех, у кого есть что-то общее.
- LEFT JOIN: Все из левой таблицы заходят, а из правой мы пригласим только тех, кто соответствует.
- RIGHT JOIN: Противоположность LEFT JOIN — правый стол главный, а левый может присоединиться, если повезет.
- 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
? Здесь начинается магия отношений.
- Первичный Ключ (Primary Key): Это как паспорт рыцаря. Уникально идентифицирует каждую строку в таблице. В нашем случае,
rycari.id
— это первичный ключ. - Внешний Ключ (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 всегда будут быстрыми, а результаты — безупречными!