Что происходит с товарами при левом join с пользователями в SQL
Что проверяют
Читаете ли вы запрос буквально: какая таблица левая, сколько строк получится и что окажется в колонках второй таблицы. Это проверка на аккуратность, потому что почти все отвечают заученной формулировкой и путают стороны соединения.
Как отвечать
Если левая таблица это товары, в результат попадут все товары, независимо от того, нашёлся ли для них пользователь. У товаров без совпадения колонки пользователя будут NULL.
select p.id, p.name, u.id as user_id
from products p
left join users u on u.id = p.user_id;Дальше назовите то, о чём обычно молчат:
- строк не меньше, чем товаров, но может быть больше: если условию соединения отвечают несколько пользователей, товар размножится по числу совпадений;
- условие в
onи условие вwhereработают по-разному. Фильтр по колонке правой таблицы вwhereотбросит строки сNULLи незаметно превратит запрос в обычныйinner join; count(u.id)не считаетNULL, аcount(*)считает, поэтому товары без владельца ищут черезwhere u.id is null.
Для C# добавьте, как это выглядит в EF Core: необязательная навигация даёт левое соединение сама, а в синтаксисе запросов его пишут связкой join ... into и DefaultIfEmpty(). Проецировать результат лучше сразу в отдельный тип, иначе материализуются лишние сущности и трекер удержит их до конца контекста.
Где спотыкаются
Путают стороны и рассказывают про всех пользователей, хотя левая таблица в вопросе это товары. Ошибка чисто механическая, но интервьюер после неё проверяет уже всё подряд, и остаток беседы идёт тяжелее.
Ждут ровно столько строк, сколько товаров, а получают дубли, потому что ключ во второй таблице не уникален. Сумма или счётчик по такому набору завышаются, и лечится это агрегацией до соединения либо проверкой уникальности ключа.
Дописывают фильтр по пользователю в where и удивляются, что товары без пользователя исчезли. Проверка простая: если условие должно оставлять строки с NULL, его место в on, потому что where применяется уже к результату соединения.