Независимо от производительности, получу ли я тот же результат из запросов A и B ниже? Как насчет C и D?
-- A
select *
from a left join b
on <blahblah>
left join c
on <blahblan>
-- B
select *
from a left join c
on <blahblah>
left join b
on <blahblan>
-- C
select *
from a join b
on <blahblah>
join c
on <blahblan>
-- D
select *
from a join c
on <blahblah>
join b
on <blahblan>
sql
join
relational-database
Просто ученик
источник
источник
<blahblah>
? Вы соединяете А с В и А с С, или вы соединяете А с В и В с С?Ответы:
Для
INNER
объединений нет, порядок не имеет значения. Запросы будут возвращать одинаковые результаты, если вы измените свой выбор сSELECT *
наSELECT a.*, b.*, c.*
.Для (
LEFT
,RIGHT
илиFULL
)OUTER
присоединяются, да, порядок имеет значение - и ( обновлено ) вещи гораздо более сложные.Во-первых, внешние соединения не являются коммутативными, поэтому
a LEFT JOIN b
не совпадают сb LEFT JOIN a
Внешние объединения также не являются ассоциативными, поэтому в ваших примерах используются оба свойства (коммутативности и ассоциативности):
эквивалентно :
но:
не эквивалентно :
Еще один (надеюсь, более простой) пример ассоциативности. Думайте об этом как
(a LEFT JOIN b) LEFT JOIN c
:Это эквивалентно , чтобы
a LEFT JOIN (b LEFT JOIN c)
:только потому, что у нас "хорошие"
ON
условия. И то,ON b.ab_id = a.ab_id
и другоеc.bc_id = b.bc_id
является проверкой на равенство и не предполагаетNULL
сравнений.Вы даже можете иметь условия с другими операторами или более сложными, такими как:
ON a.x <= b.x
илиON a.x = 7
илиON a.x LIKE b.x
или,ON (a.x, a.y) = (b.x, b.y)
и эти два запроса все равно будут эквивалентны.Однако, если какой-либо из них участвует
IS NULL
или функция, связанная с нулямиCOALESCE()
, например, если условие было выполненоb.ab_id IS NULL
, то два запроса не будут эквивалентны.источник
a.somecol > 0 OR b.someothercol > 0
; ассоциативность может потерпеть неудачу для этого условия.INNER JOIN
и следующиеLEFT JOIN
. Работает ли так, что сначала запрос будетFilter
основываться на записях,INNER JOIN
а затем будет применятьсяLEFT JOIN
кFiltered
записям?ON
предложения (т. Е. «Спецификации соединения») в новое место. , Это всего лишь синтаксис. Если вы используете нотацию реляционной алгебры (где спецификация соединения находится ниже оператора соединения), то ассоциативность становится более очевидной. Ваш аргумент только показывает, что внешние соединения не коммутативны , что правильнодля обычных соединений это не так.
TableA join TableB
будет производить тот же план выполнения, что иTableB join TableA
(ваши примеры C и D будут одинаковыми)для левого и правого присоединения это делает.
TableA left Join TableB
отличаетсяTableB left Join TableA
, но его так же, какTableB right Join TableA
источник
Если вы попытаетесь присоединиться к C на поле из B до присоединения к B, то есть:
Ваш запрос не будет выполнен, поэтому в этом случае порядок имеет значение.
источник
Оптимизатор Oracle выбирает порядок соединения таблиц для внутреннего соединения. Оптимизатор выбирает порядок объединения таблиц только в простых предложениях FROM. Вы можете проверить документацию оракула на их сайте. А для левого, правого внешнего соединения самый голосующий ответ - правильный. Оптимизатор выбирает оптимальный порядок соединения, а также оптимальный индекс для каждой таблицы. Порядок соединения может влиять на то, какой индекс является лучшим выбором. Оптимизатор может выбрать индекс в качестве пути доступа к таблице, если это внутренняя таблица, но не если это внешняя таблица (и дальнейших уточнений нет).
Оптимизатор выбирает порядок объединения таблиц только в простых предложениях FROM. Большинство объединений с использованием ключевого слова JOIN объединяются в простые объединения, поэтому оптимизатор выбирает их порядок объединения.
Оптимизатор не выбирает порядок соединения для внешних объединений; он использует порядок, указанный в заявлении.
При выборе порядка соединения оптимизатор принимает во внимание: размер каждой таблицы. Индексы, доступные для каждой таблицы. Полезен ли индекс для таблицы в определенном порядке соединения. Количество строк и страниц, которые нужно отсканировать для каждой таблицы в каждой таблице. объединить заказ
источник