В чем причина использования двойного внутреннего соединения в этом операторе SQL?

10

Я смотрю на этот старый запрос SQL. Бит, который я не могу получить, - это то, почему он дважды соединяет одну и ту же таблицу в одних и тех же столбцах. Я говорю о Table1 и Table1, связанных с псевдонимом «Table1Alias»,

SELECT DISTINCT othercolumns,
                Table1Alias.columna
FROM   maintable
       INNER JOIN secondarytable
               ON maintable.id1 = secondarytable.a_id1
       INNER JOIN table1
               ON secondarytable.id2 = table1.id3
       INNER JOIN table1 Table1Alias
               ON secondarytable.id2 = Table1Alias.id3
       INNER JOIN thirdtable
               ON table1.id4 = thirdtable.id5
       INNER JOIN fourthtable
               ON thirdtable.id6 = fourthtable.id7
       INNER JOIN fivetable
               ON thirdtable.id8 = fivetable.id9
       INNER JOIN sixthtable
               ON Table1Alias.columna = sixthtable.id10
       LEFT JOIN seventhtable
              ON thirdtable.id11 = seventhtable.id12
WHERE  LEFT(secondarytable.type123, 2) BETWEEN '01' AND '09'
       AND secondarytable.type456 = 'cate'
       AND table1.type = '0'
       AND Table1Alias.columna = 'conn'
Математика
источник

Ответы:

27

Это может помочь переписать запрос следующим образом, поэтому очевидно, что эти 2 объединения различны , т.е. объединения относятся к разным подмножествам (одной и той же таблицы):

FROM   maintable 
       INNER JOIN secondarytable 
               ON maintable.id1 = secondarytable.a_id1 
       INNER JOIN table1 
               ON secondarytable.id2 = table1.id3 
              AND table1.type = '0' 
       INNER JOIN table1 Table1Alias 
               ON secondarytable.id2 = Table1Alias.id3 
              AND Table1Alias.columna = 'conn' 
       INNER JOIN
       ...
WHERE  LEFT(secondarytable.type123, 2) BETWEEN '01' AND '09' 
       AND secondarytable.type456 = 'cate' 
ypercubeᵀᴹ
источник
не ГДЕ должно применяться ПОСЛЕ объединений, то есть я бы согласился, если бы эти ограничения были частью оператора соединения, то есть связаны с AND, но WHERE во всем опыте применяется к результату объединения, отфильтровывая строки из объединенная таблица, не влияющая на фактическое объединение.
Фрэнк Хопкинс
3
@ Darkwing Насколько я знаю, не важно, где вы ставите условия, так как работа оптимизатора запросов заключается в том, чтобы придумать лучший план исключений. Однако лучше размещать их рядом с объединениями, так как это делает их более читабельными, но это всего лишь мнение
Математика
Даже если это произойдет ПОСЛЕ присоединения, результаты объединений в конечном итоге различны. И да, объединенные строки обычно фильтруются перед объединением, поскольку это повышает производительность.
Gherman
1
Это также эквивалентно присоединению с подзапросом, например INNER JOIN (SELECT * FROM table1 WHERE type = 0) table1. Это может сделать еще более очевидным, что происходит.
Бармар
3
@ Математика - может ли условие иметь значение в ONпредложении объединения или в WHEREпредложении, может иметь большое значение, если это объединение OUTER JOIN. Если условие не выполнено в ONпредложении, основная строка все еще включается (без соответствующей внешней строки); если это не удается в WHEREпредложении, то основная строка исключается из результирующего набора.
RDFozz
8

Глядя на whereпредложение, для строки, на которую указывает строка, table1требуется столбец type= 0, а для строки, на которую указывает строка, table1aliasтребуется столбец columna= = conn.

Возможно, есть несколько строк table1для одного и того же id3?

Скотт Ходжин
источник
2

Не видя структуру таблицы - подход может заключаться в том, чтобы использовать меньший не покрывающий индекс и затем объединять в таблицу по большему покрывающему индексу, чтобы получить остаток строк, чтобы избежать операции «Поиск по ключу» и избежать изменения существующих индексов. (или если вы не можете изменить индексы)

Аллан С. Хансен
источник
2

Всякий раз, когда таблица появляется более одного раза в сложном соединении, обычно это происходит потому, что существует сущность, которая участвует в нескольких отношениях. Это, кажется, имеет место здесь, судя по ответу, который дал @Ypercube.

Сущности и отношения обычно понимаются через семантику данных и связь с основным предметом. Если ваша устаревшая система была тщательно построена, они, вероятно, позаботились о том, чтобы проанализировать предмет и тщательно определить каждый из элементов данных. Возможно, они даже создали модель сущности-отношения. Вся эта тщательная работа, возможно, была потеряна, и вы застряли, восстанавливая ее, копаясь в прошлом. Это немного похоже на археологию.

С такими именами таблиц, как Table1, мы не имеем понятия о том, как работает ваша тема. И даже если названия носят описательный характер, наше понимание предмета вашей системы может сильно отличаться от того, что необходимо в вашем случае. Это будет зависеть от вас.

Уолтер Митти
источник