Skip to main content
ClickHouse полностью поддерживает стандартные SQL JOIN, обеспечивая эффективный анализ данных. В этом руководстве вы познакомитесь с некоторыми распространёнными типами JOIN и узнаете, как использовать их с помощью диаграмм Венна и примеров запросов к нормализованному набору данных IMDB из репозитория реляционных наборов данных.

Тестовые данные и ресурсы

Инструкции по созданию и загрузке таблиц можно найти здесь. Набор данных также доступен в Песочнице ClickHouse, если вы не хотите создавать и загружать таблицы локально. Вы будете использовать следующие четыре таблицы из демонстрационного набора данных: Эти четыре таблицы содержат данные о фильмах, у которых может быть один или несколько жанров. Роли в фильмах исполняют актёры. Стрелки на диаграмме выше обозначают связи между внешним и первичным ключом. Например, столбец movie_id в строке таблицы genres содержит значение id из строки таблицы movies. Между фильмами и актёрами существует связь многие-ко-многим. Эта связь многие-ко-многим нормализуется в две связи один-ко-многим с помощью таблицы roles. Каждая строка в таблице roles содержит значения из столбцов id таблиц movies и actors.

Поддерживаемые в ClickHouse типы JOIN

ClickHouse поддерживает следующие типы JOIN: В следующих разделах мы рассмотрим примеры запросов для каждого из перечисленных выше типов JOIN.

INNER JOIN

INNER JOIN возвращает для каждой пары строк, совпадающих по ключам JOIN, значения столбцов строки из левой таблицы, объединённые со значениями столбцов строки из правой таблицы. Если для строки находится более одного совпадения, возвращаются все совпадения (то есть для строк с совпадающими ключами JOIN формируется декартово произведение). Этот запрос находит жанры для каждого фильма, объединяя таблицу movies с таблицей genres:
Ключевое слово INNER можно опустить.
Поведение INNER JOIN можно расширить или изменить с помощью одного из следующих типов JOIN.

(LEFT / RIGHT / FULL) OUTER JOIN

LEFT OUTER JOIN работает как INNER JOIN, но для несовпадающих строк левой таблицы ClickHouse возвращает значения по умолчанию для столбцов правой таблицы. Запрос RIGHT OUTER JOIN устроен аналогично и также возвращает значения из несовпадающих строк правой таблицы вместе со значениями по умолчанию для столбцов левой таблицы. Запрос FULL OUTER JOIN объединяет LEFT и RIGHT OUTER JOIN и возвращает значения из несовпадающих строк левой и правой таблиц вместе со значениями по умолчанию для столбцов правой и левой таблиц соответственно.
ClickHouse можно настроить так, чтобы он возвращал NULL вместо значений по умолчанию (однако по соображениям производительности это не рекомендуется).
Этот запрос находит все фильмы без жанра: он выбирает все строки из таблицы movies, для которых нет совпадений в таблице genres, и поэтому они получают (во время выполнения запроса) значение по умолчанию 0 для столбца movie_id:
Ключевое слово OUTER можно не указывать.

CROSS JOIN

CROSS JOIN создает полное декартово произведение двух таблиц без учета ключей JOIN. Каждая строка из левой таблицы объединяется с каждой строкой из правой таблицы. Таким образом, следующий запрос объединяет каждую строку из таблицы movies с каждой строкой из таблицы genres:
Хотя предыдущий пример запроса сам по себе не имел особого смысла, его можно дополнить условием WHERE, чтобы сопоставить совпадающие строки и воспроизвести поведение INNER JOIN при поиске жанров для каждого фильма:
Альтернативный синтаксис CROSS JOIN позволяет указать несколько таблиц в предложении FROM, разделяя их запятыми. ClickHouse переписывает CROSS JOIN в INNER JOIN, если в разделе WHERE запроса есть выражения для JOIN. Это можно проверить на примере запроса с помощью EXPLAIN SYNTAX (он возвращает синтаксически оптимизированную версию, в которую запрос переписывается перед выполнением):
В синтаксически оптимизированной версии запроса CROSS JOIN предложение INNER JOIN содержит ключевое слово ALL, явно добавленное для сохранения семантики декартова произведения CROSS JOIN даже при переписывании в INNER JOIN, для которого декартово произведение можно отключить.
И поскольку, как упоминалось выше, ключевое слово OUTER в RIGHT OUTER JOIN можно опустить, а необязательное ключевое слово ALL — добавить, можно написать ALL RIGHT JOIN, и это тоже будет работать.

(LEFT / RIGHT) SEMI JOIN

Запрос LEFT SEMI JOIN возвращает значения столбцов для каждой строки из левой таблицы, у которой есть хотя бы одно совпадение по ключу JOIN в правой таблице. Возвращается только первое найденное совпадение (декартово произведение отключено). Запрос RIGHT SEMI JOIN работает аналогично и возвращает значения для всех строк из правой таблицы, у которых есть хотя бы одно совпадение в левой таблице, но возвращается только первое найденное совпадение. Этот запрос находит всех актёров и актрис, сыгравших в фильме в 2023 году. Обратите внимание: при обычном (INNER) JOIN один и тот же актёр или актриса может появиться несколько раз, если в 2023 году у него или у неё было больше одной роли:

(LEFT / RIGHT) ANTI JOIN

LEFT ANTI JOIN возвращает значения столбцов для всех несовпадающих строк левой таблицы. Аналогично, RIGHT ANTI JOIN возвращает значения столбцов для всех несовпадающих строк правой таблицы. Альтернативный вариант запроса из предыдущего примера с outer JOIN — использовать anti JOIN, чтобы найти фильмы, у которых в наборе данных не указан жанр:

(LEFT / RIGHT / INNER) ANY JOIN

LEFT ANY JOIN — это комбинация LEFT OUTER JOIN и LEFT SEMI JOIN, то есть ClickHouse возвращает значения столбцов для каждой строки из левой таблицы: либо в сочетании со значениями столбцов совпавшей строки из правой таблицы, либо со значениями столбцов правой таблицы по умолчанию, если совпадения нет. Если для строки из левой таблицы в правой таблице найдено более одного совпадения, ClickHouse возвращает только объединённые значения столбцов из первого найденного совпадения (декартово произведение отключено). Аналогично, RIGHT ANY JOIN — это комбинация RIGHT OUTER JOIN и RIGHT SEMI JOIN. А INNER ANY JOIN — это INNER JOIN с отключённым декартовым произведением. Следующий пример показывает LEFT ANY JOIN на абстрактном примере с использованием двух временных таблиц (left_table и right_table), созданных с помощью values табличной функции:
Это тот же запрос, но с RIGHT ANY JOIN:
Вот запрос с INNER ANY JOIN:

ASOF JOIN

ASOF JOIN предоставляет возможность неточного сопоставления. Если для строки из левой таблицы не находится точного совпадения в правой таблице, в качестве совпадения используется наиболее близкая строка из правой таблицы. Это особенно полезно для анализа временных рядов и может значительно снизить сложность запроса. В следующем примере выполняется анализ временных рядов на данных фондового рынка. Таблица quotes содержит котировки тикеров акций для определённых моментов времени в течение дня. В примере цена обновляется каждые 10 секунд. Таблица trades содержит сделки по тикерам: определённый объём акций был куплен в определённое время: Чтобы вычислить фактическую стоимость каждой сделки, нужно сопоставить сделки с ближайшим временем котировки. С ASOF JOIN это делается просто и компактно: условие ON используется для задания точного совпадения, а условие AND — для задания ближайшего совпадения. Для конкретного тикера (точное совпадение) нужно найти строку с «ближайшим» временем из таблицы quotes, которое точно совпадает со временем сделки по этому тикеру или предшествует ему (неточное совпадение):
Условие ON в ASOF JOIN является обязательным и задаёт условие точного совпадения наряду с условием неточного совпадения в условии AND.

Кратко

В этом руководстве показано, что ClickHouse поддерживает все стандартные типы SQL JOIN, а также специальные варианты JOIN для аналитических запросов. Подробнее о JOIN см. в документации по оператору JOIN.
Последнее изменение 23 июля 2026 г.