Для INNER
присоединений нет, порядок не имеет значения. Запросы будут возвращать одинаковые результаты, если вы измените выбор с SELECT *
на SELECT a.*, b.*, c.*
.
Для (LEFT
, RIGHT
или FULL
) OUTER
объединений, да, порядок имеет значение - и ( updated ) все гораздо сложнее.
Во-первых, внешние соединения не являются коммутативными, поэтому a LEFT JOIN b
отличается от b LEFT JOIN a
Внешние объединения также не являются ассоциативными, поэтому в ваших примерах используются свойства (коммутативности и ассоциативности):
a LEFT JOIN b
ON b.ab_id = a.ab_id
LEFT JOIN c
ON c.ac_id = a.ac_id
эквивалентно :
a LEFT JOIN c
ON c.ac_id = a.ac_id
LEFT JOIN b
ON b.ab_id = a.ab_id
но:
a LEFT JOIN b
ON b.ab_id = a.ab_id
LEFT JOIN c
ON c.ac_id = a.ac_id
AND c.bc_id = b.bc_id
не эквивалентно :
a LEFT JOIN c
ON c.ac_id = a.ac_id
LEFT JOIN b
ON b.ab_id = a.ab_id
AND b.bc_id = c.bc_id
Еще один (надеюсь, более простой) пример ассоциативности. Думайте об этом как (a LEFT JOIN b) LEFT JOIN c
:
a LEFT JOIN b
ON b.ab_id = a.ab_id -- AB condition
LEFT JOIN c
ON c.bc_id = b.bc_id -- BC condition
Этот эквивалентен a LEFT JOIN (b LEFT JOIN c)
:
a LEFT JOIN
b LEFT JOIN c
ON c.bc_id = b.bc_id -- BC condition
ON b.ab_id = a.ab_id -- AB condition
только потому, что у нас "хорошие" 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
, то эти два запроса не будут эквивалентны.