Есть ответы
Как соединить две таблицы в MySQL - JOIN не дает нужный результат

Застрял на простой (казалось бы) задаче. Есть две таблицы:

users (id, name, city_id)
cities (id, city_name)

Хочу получить список всех пользователей с названием их города. Пробовал INNER JOIN - не показывает пользователей у которых city_id = NULL. Попробовал просто перечислить таблицы через запятую - получил декартово произведение.

MySQL 8.0, локальная база для учебного проекта. Что делаю не так и какой JOIN нужен в моем случае?

17
Эксперт • 1 ответ

LEFT JOIN вместо INNER JOIN:

SELECT u.name, c.city_name
FROM users u
LEFT JOIN cities c ON u.city_id = c.id;

INNER JOIN возвращает только строки где есть совпадение в обеих таблицах. LEFT JOIN возвращает все строки из левой таблицы (users), а для тех у кого нет города - ставит NULL в колонку city_name.

Аватар Алиса Морозова

WHERE c.id IS NULL добавь в конец запроса.

Аватар Виктор Кузнецов

Спасибо, заработало! Теперь понял разницу. А если хочу показать только пользователей БЕЗ города - как фильтровать?

8
Участник • 2 ответа

Разберем все виды JOIN чтобы ты понял логику, а не просто скопировал ответ.

INNER JOIN - пересечение. Строки возвращаются только если ключ есть в обеих таблицах. Пользователь без city_id или с city_id которого нет в таблице cities - пропадает.

LEFT JOIN - все из левой таблицы плюс совпадения из правой. Пользователь без города останется, city_name будет NULL.

RIGHT JOIN - зеркально, все из правой. Редко используется, обычно просто меняют порядок таблиц и пишут LEFT.

FULL OUTER JOIN - все строки из обеих таблиц. В MySQL нет нативно, эмулируется через UNION.

Для твоей задачи нужен LEFT JOIN. Это 90% реальных запросов с соединением таблиц - один главный объект (users) и опциональные данные к нему (город).

2
Эксперт • 1 ответ

Кстати если хочешь понять JOIN визуально - загугли "SQL joins venn diagram". Картинка с кругами Эйлера объяснит за 10 секунд то что я писал бы 3 абзаца.

Написать ответ

Премодерация гостей

Вы отвечаете как гость. Ваш ответ будет скрыт до проверки модератором. Чтобы ответ появился сразу и вы получали репутацию — войдите в аккаунт.

Будьте вежливы и соблюдайте правила платформы.