Отвечу на вопросы, которые возникают у новичков в SQL, в частности в PostgreSQL и BigQuery. Мы не будем обсуждать совсем базовые SELECT, CREATE или DROP.
Для удобства восприятия будем использовать тестовые данные. Первая таблица players содержит данные о пользователях и дате установки мобильной игры:
|playerId|name |installationDate|game |os |
|--------|----------------|----------------|----------|----------|
|9e8a0174|Трофимова Алёна |2023-07-30 |basketball|iOS 16 |
|3e2e04ad|Семенова Алиса |2022-07-21 |consumer |iOS 13 |
|642eafb2|Абрамова Диана |2022-06-06 |curtain |iOS 15 |
|8c231f49|Ефимова Ульяна |2022-06-21 |conductor |Android 12|
|a085caf1|Захаров Михаил |2023-04-11 |appear |Android 11|
|c4deb869|Николаева Марта |2022-03-31 |possible |iOS 11 |вторая, levels, — даты прохождения игроком с определенным ID того или иного уровня:
|playerId|level|completionDate|
|--------|-----|--------------|
|7b50274d|6 |2023-05-17 |
|b0c9a9da|20 |2022-02-19 |
|09b3d5b5|15 |2022-07-22 |
|52b3bfa9|11 |2022-02-18 |
|3e2e04ad|17 |2022-08-17 |
|642eafb2|17 |2022-04-14 |
|8c231f49|20 |2022-05-30 |
|a085caf1|20 |2023-02-24 |
|36545ec1|16 |2022-08-10 |
|44e9653f|3 |2023-06-02 |Я буду верстать в BigQuery на таком же датасете, так что использую соответствующий диалект.
INNER JOIN
Это тип объединения по умолчанию, и он оставит наименьшее число строк. Слово INNER можно опустить:
SELECT
p.playerId,
installationDate,
game,
level,
completionDate
FROM `project.tutorials.players` AS p
JOIN `project.tutorials.levels` AS l ON p.playerId = l.playerId;Посмотрим, что здесь происходит:
• В строках 1-6 мы выбираем только необходимые столбцы;
• 7-8: командой AS задаем псевдонимы таблицам;
• 8: определяем логику объединения по совпадающим playerId. Это означает также, что мы сохраним данные только об первом попавшемся уровне.
Получим всего четыре строки:
|playerId|name |installationDate|game |level|completionDate|
|--------|--------------|----------------|---------|-----|--------------|
|3e2e04ad|Семенова Алиса|2022-07-21 |consumer |17 |2022-08-17 |
|642eafb2|Абрамова Диана|2022-06-06 |curtain |17 |2022-04-14 |
|8c231f49|Ефимова Ульяна|2022-06-21 |conductor|20 |2022-05-30 |
|a085caf1|Захаров Михаил|2023-04-11 |appear |20 |2023-02-24 |
OUTER JOIN
Этот тип объединения, напротив, куда «добрее» и в случае FULL-объединения сохранит записи обо всех игроках и всех пройденных уровнях:
SELECT
p.playerId,
installationDate,
game,
level,
completionDate
FROM `project.tutorials.players` AS p
FULL OUTER JOIN `project.tutorials.levels` AS l ON p.playerId = l.playerId;У нас появятся записи, где playerId пуст, поскольку попросили мы идентификаторы только из первой таблицы:
🔍 Читать
@sqlhub