このSQLステートメントで二重内部結合を使用する理由は何ですか?


10

このレガシーSQLクエリを見ています。取得できないビットは、同じ列で同じテーブルを2回内部結合している理由です。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' 

結合の後に適用されるWHEREではありません。つまり、これらの制約が結合ステートメントの一部である場合、つまりANDで接続されている場合は同意しますが、すべてのエクスペリエンスのWHEREは、結合からの行を除外する結合の結果に適用されます結合されたテーブル。実際の結合には影響しません。
フランクホプキンス

3
@Darkwing私が知る限り、条件をどこに置くかは問題ではありません。クエリオプティマイザが最善の実行計画を立てることが仕事だからです。ただし、読みやすくするため、結合の隣に配置する方が適切ですが、それは単なる見解です
数学

結合後に発生したとしても、結合の結果は最終的に異なります。そして、はい、結合された行は、パフォーマンスを向上させるため、結合する前に通常フィルタリングされます。
ガーマン2018

1
これは、サブクエリと結合するのと同じINNER JOIN (SELECT * FROM table1 WHERE type = 0) table1です。これにより、何が起こっているのかがさらに明確になります。
Barmar 2018

3
@Mathematics-条件がON結合の句にあるか、句にあるWHEREかは、結合がの場合、非常に重要OUTER JOINです。条件がON句で失敗した場合でも、プライマリ行は含まれます(一致する外部行なし)。WHERE句で失敗した場合、プライマリ行は結果セットから除外されます。
RDFozz 2018

8

見てwhere句、行はによって指されているtable1カラムが必要typeで指されている=「0」と行にtable1aliasカラム必要columna=でCONN 'にあります。

おそらくtable1、同じ行に複数の行がありid3ますか?


2

テーブル構造を確認せずに-小さい非カバリングインデックスを利用し、大きなカバリングインデックスのテーブルに結合して残りの行を取得し、「キールックアップ」操作を回避し、既存のインデックスの変更を回避するアプローチ(または、インデックスを変更できない場合)


2

複雑な結合でテーブルが複数回出現する場合、それは通常、複数の関係に参加しているエンティティがあるためです。これは、@ Ypercubeの回答から判断すると、ここに当てはまるようです。

エンティティと関係は一般に、データのセマンティクスと、基礎となる主題への接続を通じて理解されます。レガシーシステムが注意深く構築されている場合、おそらくそれらは主題を分析し、各データ要素を注意深く定義するためにいくらか注意を払いました。エンティティリレーションシップモデルを構築している場合もあります。その注意深い作業はすべて失われた可能性があり、過去を掘り下げて再構築するのに行き詰まっています。これは考古学に少し似ています。

Table1のようなテーブル名では、主題がどのように機能するかについての手がかりがありません。また、名前が説明的なものであったとしても、システムの主題についての私たちの理解は、ケースで必要とされるものとは大きく異なる場合があります。それはあなた次第です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.