1. ホーム
  2. sql

[解決済み] 同じテーブルに2回結合する最も良い方法は何ですか?

2022-07-12 13:17:29

質問

少し複雑なのですが、2つのテーブルがあります。仮にこのような構造だとします。

*Table1*
ID
PhoneNumber1
PhoneNumber2

*Table2*
PhoneNumber
SomeOtherField

テーブルは、Table1.PhoneNumber1 -> Table2.PhoneNumber, または Table1.PhoneNumber2 -> Table2.PhoneNumber に基づいて結合することが可能です。

さて、PhoneNumber1、PhoneNumber1 に対応する SomeOtherField、PhoneNumber2、および PhoneNumber2 に対応する SomeOtherField を含む結果セットを取得したいのですが、どうすればよいでしょうか。

これを行うための2つの方法を考えました - テーブルに2回結合するか、ON句でORを使用して1回結合するかです。

方法1 :

SELECT t1.PhoneNumber1, t1.PhoneNumber2, 
   t2.SomeOtherFieldForPhone1, t3.someOtherFieldForPhone2
FROM Table1 t1
INNER JOIN Table2 t2
   ON t2.PhoneNumber = t1.PhoneNumber1
INNER JOIN Table2 t3
   ON t3.PhoneNumber = t1.PhoneNumber2

これはうまくいきそうです。

方法2 :

どうにかして、以下のようなクエリにする。

SELECT ...
FROM Table1
INNER JOIN Table2 
   ON Table1.PhoneNumber1 = Table2.PhoneNumber OR
      Table1.PhoneNumber2 = Table2.PhoneNumber

私はまだこれがうまくいっていないので、方法があるかどうかわかりません。

これを達成するための最良の方法は何でしょうか?どちらの方法も単純で直感的とは思えません...。これを行うより簡単な方法はありますか? この要件は一般的にどのように実装されているのでしょうか?

どのように解決するのですか?

最初に、私はこれらのテーブルをリファクタリングして、自然キーとして電話番号を使用するのをやめようと思います。私は自然キーが好きではありませんが、これはその理由を示す良い例です。自然キー、特に電話番号のようなものは、変更される可能性があり、頻繁に変更されます。特に電話番号のような自然キーは変更される可能性があり、しかも頻繁に。変更時にデータベースを更新するのは、膨大でエラーを起こしやすい頭痛の種になります。*

方法1 がベストな方法です。名前付けのスキームと短いエイリアスのため、少し退屈に見えますが... エイリアスは同じテーブルを複数回結合したり、サブクエリなどを使用したりするときの友です。

私だったら、ちょっとだけきれいにします。

SELECT t.PhoneNumber1, t.PhoneNumber2, 
   t1.SomeOtherFieldForPhone1, t2.someOtherFieldForPhone2
FROM Table1 t
JOIN Table2 t1 ON t1.PhoneNumber = t.PhoneNumber1
JOIN Table2 t2 ON t2.PhoneNumber = t.PhoneNumber2

私がしたこと

  • INNER を指定する必要はありません - LEFT や RIGHT を指定しないことで暗黙の了解となっています。
  • プライマリ・ルックアップ・テーブルに n サフィックスを付けない。
  • 何度も使用するテーブルのエイリアスは、それが明白になるように N サフィックスを付けます。

*DBA が自然キーの更新の頭痛の種を避ける方法の 1 つは、主キーと外部キー制約を指定しないことで、貧弱なデータベース設計の問題をさらに悪化させることです。私は実際にこれをより頻繁に目にしてきました。