У чому причина використання подвійного внутрішнього з'єднання в цьому операторі SQL?


10

Я переглядаю цей застарілий запит SQL. Біт, який я не в змозі отримати - це те, що це внутрішнє з'єднання однієї таблиці двічі в одних і тих же стовпцях. Я говорю про таблицю1 та таблицю1, об'єднану з псевдонімом "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

Це може допомогти переписати запит таким чином, тому очевидно, що два об'єднання є різними , тобто приєднання до різних підмножин (з тієї ж таблиці):

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' 

Чи не застосовуватись БУДІ ПІСЛЯ з'єднань, тобто я погоджувався б, якщо б ці обмеження були частиною заяви заяви про з'єднання, тобто з'єднані з AND, але де БЕЗ у всьому досвіді застосовується до результату фільтрації приєднання з рядків об'єднана таблиця, не впливаючи на фактичне з'єднання.
Френк Хопкінс

3
@Darkwing Наскільки я знаю, не важливо, де ви ставите умови, оскільки це завдання оптимізатора запитів, щоб скласти найкращий план винятків. Однак краще поставити їх поруч з приєднаннями, оскільки це робить їх більш читабельними, але це лише думка
Математика

Навіть якби це сталося ПІСЛЯ приєднання, результати злучень зрештою відрізняються. І так, з'єднані рядки зазвичай фільтруються перед тим, як приєднатися, оскільки це покращує продуктивність.
Герман

1
Це також рівнозначно об'єднанню з підзапитом, наприклад INNER JOIN (SELECT * FROM table1 WHERE type = 0) table1. Це може зробити ще більш очевидним, що відбувається.
Бармар

3
@Mathematics - чи є умова в ONпункті приєднання або в WHEREпункті, може мати велике значення, якщо об'єднання є OUTER JOIN. Якщо умова не відповідає в ONпункті, первинний рядок все одно включається (без відповідного зовнішнього рядка); якщо він не відповідає в WHEREпункті, то первинний рядок виключається з набору результатів.
RDFozz

8

Дивлячись на whereпункт, рядок, на який вказує, table1вимагає стовпця type= '0', а рядок, на який вказує, table1aliasвимагає стовпця columnaдо = 'conn'.

Можливо, є кілька рядків table1для одного і того ж id3?


2

Не бачачи структури таблиці - підходом може бути використання меншого не охоплюючого індексу, а потім приєднання до таблиці з більшим індексом покриття, щоб отримати залишки рядків, щоб уникнути операції «Ключовий пошук» та уникнути зміни існуючих індексів (або якщо ви не можете змінити індекси)


2

Кожен раз, коли таблиця з’являється не раз у складному з'єднанні, це зазвичай тому, що існує сутність, яка бере участь у більш ніж одних відносинах. Це, мабуть, так і тут, судячи з відповіді, яку дав @Ypercube.

Суб'єкти та відносини, як правило, розуміються через семантику даних та зв’язок із основним предметом. Якщо ваша застаріла система була ретельно побудована, вони, ймовірно, подбали про те, щоб проаналізувати предмет та ретельно визначити кожен із елементів даних. Можливо, вони навіть побудували модель взаємовідносин між особою. Вся ця ретельна робота, можливо, була втрачена, і ви застрягли, реконструюючи її, копаючись у минуле. Це трохи схоже на археологію.

З іменами таблиці, як Table1, ми не маємо поняття про те, як працює ваш предмет. І навіть якщо назви були описовими, наше розуміння теми вашої системи може сильно відрізнятися від того, що потрібно у вашому випадку. Це буде залежати від вас.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.