1. ホーム
  2. sql

[解決済み] SQLの結合形式 - 入れ子になった内側join

2022-03-13 18:44:41

質問

私がリファクタリングしているレガシーシステムに、以下のようなSQL文があります。この質問の目的のために省略したビューで、当面はcount(*)を返すだけです。

SELECT COUNT(*)
FROM Table1 
    INNER JOIN Table2 
        INNER JOIN Table3 ON Table2.Key = Table3.Key AND Table2.Key2 = Table3.Key2 
    ON Table1.DifferentKey = Table3.DifferentKey

非常に多くのレコードを生成し、システムを殺しているのですが、どなたか構文を説明していただけませんか?また、これは何か他の方法で表現できるのでしょうか?

  • テーブル1には419行が含まれる
  • テーブル2には3374行が含まれる
  • テーブル3は28182行を含む

EDIT

再フォーマットの提案

SELECT COUNT(*)
FROM Table1 
    INNER JOIN Table3
          ON Table1.DifferentKey = Table3.DifferentKey
    INNER JOIN Table2 
          ON Table2.Key = Table3.Key AND Table2.Key2 = Table3.Key2

解決方法は?

読みやすくするために、クエリを再構築しました...見かけ上の最上位はテーブル1で、次にテーブル3が結びつき、テーブル3はテーブル2に結びつきます。 関係の連鎖をたどれば、ずっと簡単です。

さて、質問にお答えします。 デカルト積の結果、大きなカウントが得られていますね。 Table1のレコードがTable3でマッチするごとにX * Yが得られ、Table3とTable2がマッチするごとに同じ影響があります... Y * Z... したがって、テーブル1の1つの可能なIDに対する結果は、X * Y * Zのレコードを持つことができます。

これは、テーブルの正規化または内容がどのようになっているのか、キーがPRIMARYキーなのかそうでないのかがわからないことに基づいています。

Ex:
Table 1       
DiffKey    Other Val
1          X
1          Y
1          Z

Table 3
DiffKey   Key    Key2  Tbl3 Other
1         2      6     V
1         2      6     X
1         2      6     Y
1         2      6     Z

Table 2
Key    Key2   Other Val
2      6      a
2      6      b
2      6      c
2      6      d
2      6      e

つまり、テーブル1とテーブル3を結合すると、(このシナリオでは)12レコード(1の各レコードと3の各レコードを結合したもの)になります。 そして、テーブル2のマッチしたレコード(5レコード)をすべてもう一度...合計60(3 tbl1 * 4 tbl3 * 5 tbl2)カウントが返されます。

さて、これを1000件以上のレコードに展開すると、いかに混乱した構造が牛の首を絞め、パフォーマンスを低下させるかがわかるでしょう。

SELECT
      COUNT(*)
   FROM
      Table1 
         INNER JOIN Table3
            ON Table1.DifferentKey = Table3.DifferentKey
            INNER JOIN Table2
               ON Table3.Key =Table2.Key
               AND Table3.Key2 = Table2.Key2