Просто JOIN – это та же хрень (CROSS). Здесь нужен именно LEFT JOIN – расширить записи одной таблицы полями из др. Он круто оптимизируется, когда присоединяются данные из «словарей». Нет даже попытки изменить кол-во записей из осн. таблицы, дублируя их.
Миша, не могу согласиться. LEFT JOIN одна из хреней, которые надо использовать редко. Когда ты точно знаешь, что он необходим. Так же как null-able поля. Так же как DISTINCT. Всё это вещи хорошие, для своего правильного места. Но когда их лепят просто ВЕЗДЕ, это признак что код говнякают, а не пишут. Ибо отсутствующая запись в "словаре" это, блин, АХТУНГ! Неконсистентные данные. Ошибочная ситуация должна приводить к поведению, на которое обратишь внимание и исправишь. А не "авось и так будет работать". --- Добавлено --- @Булат Азат улы сейчас совсем запутается. Приношу свои извинения )) --- Добавлено --- Вот почитай чтобы понимать больше про соединения (join): нагуглил по быстрому - https://learndb.ru/articles/article/30 ( Update: ^^^ это был совет ТСу, а не miketomlin )
Это понятно. Но еще больший АХТУНГ – потеря в выборке требуемых записей из-за «проблемы» (это не всегда проблема) с каким-то словарем! Ты наверняка знаешь о возможностях СУБД по жесткому контролю полноты словарей. Неполнота тоже может быть допустима: вывод пустых ячеек или черточек в них вместо NULL – вполне вменяемая практика. LEFT JOIN предназначен для раскрытия внешних ключей (задача ТС'а). Когда ты говоришь, что это редкая задача, я даже не знаю, что ответить. P.S. В мускуле INNER и CROSS (и просто JOIN) – полные эквиваленты, так что для меня это одна хрень. Т.е. (INNER) JOIN – в данном случае тоже хрень, если кого-то напрягло слово CROSS.
Давай по порядку. Во имя истины, а не сратча для ))) Утверждение: Всё смешалось здесь. Нет такого термина "расширение" в РСУБД. Все join-ы, предназначены для, внезапно™, соединения данных из разных множеств по какому-то условию (не обязательно равенству) в общие строки. Для простоты ограничимся равенством значений. И будем говорить только о таблицах, хотя объединять можно целые выражения или "подзапросы". Внешнее (LEFT или RIGHT) соединение отличается тем, что при невыполнении условия объединения, одна из половинок всё равно будет присутствовать в результате. А на месте отсутствующих данных другой половины будут NULL. Оптимизация здесь вообще не при чем — непонятно с чего здесь этот термин. Это математические отношения, а не способ что-то ускорить. Про "дубли" тоже невпопад. Повторяющиеся данные могут появиться когда объединяемые таблицы связаны один-ко-многим. Такое отношение даст повторы для данных из таблицы со стороны где "один-" ))) И здесь нет разницы INNER или LEFT, всё равно будут дубли.
Утверждение: Откуда такое вообще? Внешнее соединение предназначено для нахождения всех записей, для которых есть данные хотябы в одной (здесь в левой - LEFT) из таблиц. И допускает отсутствие связанных данных в другой таблице. Внешние ключи (foreign keys) это отдельная тема. Не к месту употребил. Утверждение: Для тебя возможно, а вообще — нет. INNER JOIN можно записать как просто JOIN. Но CROSS JOIN это особый вид соединения - перекрестное. Как это принято в интернетах, покажем в картинках для простоты: vs. vs. --- Добавлено --- Для CROSS JOIN не надо писать условие ON. Какие-то диалекты, например Postgress, это прямо запрещает, выдаёт ошибку «syntax error at or near "ON"» Что касается "В мускуле полные эквиваленты", то MySQL не выдаст ошибку синтаксиса, а проглотит. Исторически так сложилось, что он многие ошибки игнорит. Но вообще по стандартам "ON" там лишний и соединение это имеет отдельный смысл. CROSS JOIN скорее аналог перечисления таблиц через запятую во FROM, а никак не INNER JOIN !!! Короче, призываю правильно пользоваться терминологией и не косячить, даже если синтаксическая ошибка не возникает. Логические ошибки куда хуже! --- Добавлено --- В исходной теме ТС никак не намекал что ему надо чтобы слева было, а справа могло быть пусто. ))) Но ты стал "оптимизировать" и проталкивать внешнее соединение. П о ч е м у ? Утверждение: надо внимательно читать прежде чем не знать что ответить: Я говорю: НАДО использовать редко, а не редкая задача. И аргументирую почему. Надо стараться писать правильно, надо знать матчасть, надо делать так, чтобы ошибочные данные себя обнаруживали, а не маскировать проблемы. Хорошо бы использовать внешние ключи чтобы исключить саму возможность неправильных данных для многих кейсов. Нет смысла в LEFT JOIN просто сцк везде. Peace!
@artoodetoo, ну, раз пошла такая пьянка, тоже попробую объяснить на пальцах... device-record-1 model-name marka-name device-record-2 model-name marka-name (имена моделей/марок могут быть разные). Не может быть такого (когда присоединяются данные из «словарей»): device-record-1 model-name marka-name device-record-1 model-name marka-name device-record-2 model-name marka-name device-record-2 model-name marka-name (сокращения кол-ва записей тоже быть не может без доп. фильтрации, независимо от полноты словарей, – это и отличает LEFT JOIN от JOIN). Да, СУБД умеет оптимизировать выполнение запросов, когда обрабатываемые данные имеют определенные ограничения. Не нужно стрелять из пушки по воробьям. ТС как раз-таки «раскрывает внешние ключи» – по id-шкам «добирает» данные из соответствующих словарей. Так что все очень даже к месту! Странно, что кто-то «понимающий» этого не видит. Здесь написано, что (INNER) JOIN и CROSS (с WHERE) – одна хрень. Не решает задачу ТС'а. Ну, в конце пошло объяснение основ, которые я знаю. Кстати, мне говорили спецы, что показанные диаграммы плохо описывают виды запросов, не раскрывают все детали происходящего и могут даже ввести в заблуждение.