powered by simpleCommunicator - 2.0.31     © 2024 Programmizd 02
Форумы / Другие СУБД [игнор отключен] [закрыт для гостей] / Для SELECT * FROM TableA a JOIN TableB b ON аргументы за a.col = b.col и за b.col = a.col
3 сообщений из 3, страница 1 из 1
Для SELECT * FROM TableA a JOIN TableB b ON аргументы за a.col = b.col и за b.col = a.col
    #39968190
Nashev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
С точки зрения производительности оба варианта равноценны.
Код: sql
1.
2.
SELECT * FROM TableA a JOIN TableB b ON a.col = b.col
SELECT * FROM TableA a JOIN TableB b ON b.col = a.col


А вот с точки зрения логики запроса, удобства воприятия и написания кто что себе на этот счёт думает?

Первый вариант - условно говоря, поля в сравнении появляются в порядке появления таблиц в запросе, а второй - сначала названо поле присоединяемой таблицы, и затем оно сравнивается с полями из уже описанной на этот момент выборки
...
Рейтинг: 0 / 0
Для SELECT * FROM TableA a JOIN TableB b ON аргументы за a.col = b.col и за b.col = a.col
    #39968204
Nashev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Некоторое гугление на данную тему дало следующее:

https://postgrespro.ru/docs/postgresql/9.6/queries-table-expressions - дока по Постгресу - говорит просто: пишите там сравнения. И приводит пример с полями в порядке упоминания таблиц

https://docs.microsoft.com/ru-ru/sql/relational-databases/performance/joins?view=sql-server-ver15 - MS SQL Server - так же.

https://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqlj18922.html - так же, но в примерах ещё и нарочитое разнообразие - в первом с алиасами и в порядке по второму моему образцу, во втором - без алиасов, и в порядке по первому образцу. Да ещё и регистр скачет как хочет.

https://www.oracletutorial.com/oracle-basics/oracle-left-join/ - сайт обучающий про Оракл - тоже разнообразие наблюдается. К тому же тут пишут The query compares each row in the T1 table with rows in the T2 table., хотя на самом деле всё наоборот, и правильно было б The query compares rows in the T2 table with each row in the T1 table.

Нашёлся и аналогичный вопрос на SO - https://stackoverflow.com/questions/24428427/best-practices-for-the-order-of-joined-columns-in-a-sql-join - там я отписался с аргументом в пользу второго, а до меня - кто-то отписался в пользу второго, но сослался на вкусы и не аргументировал, кто-то отписался в пользу первого, сказав что его так учили, и двое ответили не в тему, сказав что на производительность не влияет.

Ещё я попробовал почитать стандарт http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt, дык там так мудрёно написано, что я не пойму, касаются ли они вообще этого вопроса ((
...
Рейтинг: 0 / 0
Для SELECT * FROM TableA a JOIN TableB b ON аргументы за a.col = b.col и за b.col = a.col
    #39968230
Nashev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ещё интересный аспект здесь - а что с другими видами JOIN?

Что такое вообще JOIN в логике SQL-запроса? Запрос строит выборку. Выборка в запросе описывается последовательно, на языке, практически читаемом как цельная понятная фраза: мы SQL-машине, фактически, говорим строить итоговую выборку, взяв строки вот отсюда, а ещё подключить к ним строки ещё и отсюда, и ещё вот отсюда и т.п. То есть, JOIN - это операция добавления ещё одной группы строк к уже собранной предыдущими инструкциями группе строк. Когда джойним очередную таблицу, можно сказать что мы добавляем эту одну таблицу к уже собранной выборке. То есть, для каждого JOIN у нас на входе есть уже отобранная выборка (всё, что получилось в итоге сборки всего что выше по тексту запроса), есть добавляемая таблица и в итоге на выходе из каждого JOIN получается его итоговая выборка , которая станет исходной выборкой для следующего JOIN, если такой в запросе есть.

Оптимизатор SQL-машины, конечно, может всё это выполнять в другом порядке, и скорее всего каждую промежуточную выборку вовсе не будет формировать отдельно, но с точки зрения логики написания запроса - всё именно так.

Теперь про виды JOIN-ов.

Как выполняется запрос при LEFT JOIN ? Для каждой записи уже отобранной выборки ищутся записи в добавляемой таблице, и если такие есть - она сопоставляется каждой из них, и полученное добавляется в итоговую выборку, если нет - итоговая выборка дополняется строкой с null-ами, и запись исходной выборки сопоставляется с ней. Записи добавляемой таблицы, для которых в исходной выборке соответствия не нашлось, в итоговую выборку не попадают.

Таким образом, мы в описании добавления таблицы указываем, какие именно записи добавляемой таблицы должны найтись, чтоб пополнить выборку. Мы говорим про очередную запись из добавляемой таблицы и накладываем условие именно на неё.

И в первом варианте получается фраза типа:
Давайте позовём Васю. Какого? Ну, вот у Пети он друг, и светлые волосы у этого Васи, и много денег тоже у этого Васи.

А во втором - вот так:
Давайте позовём Васю. Какого? Ну, тот Вася который друг Пети, у которого светлые волосы и у которого много денег.

Второе - органичнее, нет?

Условие для простого JOIN, без приписок (того, который допускает бесполезную приписку INNER ) - всё ровно так же, только при отсутствии записи в добавляемой таблице запись исходной выборки пропускается. Условие, фактически, можно читать ровно так же, как читается условие для LEFT.

Как выполняется запрос при RIGHT JOIN ? Для каждой записи добавляемой таблицы ищутся записи в уже отобранной выборке, и если такие есть - она сопоставляется им и добавляется в итоговую выборку, если нет - итоговая выборка дополняется строкой с null-ами, и запись добавляемой таблицы сопоставляется ей. Записи исходной выборки, для которых в добавляемой таблице соответствия не нашлось, в итоговую выборку не попадают.

Таким образом, для right join условие логично записать про соответствие выборки добавляемой таблице, то есть в выражениях поля выборки указывать слева, а поля добавляемой таблицы справа.

А что с FULL JOIN ? Там исходная выборка и добавляемая таблица симметричны, обе дополняются пустыми полями если не найдено встречной записи, но если участь, что мы всё ж к выборке добавляем что-то новое, логично про это новое и что-либо утверждать, то есть условие логично писать как для LEFT JOIN.

Для CROSS JOIN условий нет, и вопроса нет. Но логика ровно та же - идём по выборке, и для каждой записи ходим по добавляемой таблице.

ИТОГО: Всё кроме RIGHT JOIN, логично укладывается во второй образец. (Я вообще считаю, что right join вообще излишество, наляпанное чисто для симметрии! Он скорее вреден, чем полезен.) И меня чрезвычайно удивляет, почему столь популярен первый.
...
Рейтинг: 0 / 0
3 сообщений из 3, страница 1 из 1
Форумы / Другие СУБД [игнор отключен] [закрыт для гостей] / Для SELECT * FROM TableA a JOIN TableB b ON аргументы за a.col = b.col и за b.col = a.col
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]