[解決済み] 同じテーブルに2回結合する最も良い方法は何ですか?
質問
少し複雑なのですが、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 つは、主キーと外部キー制約を指定しないことで、貧弱なデータベース設計の問題をさらに悪化させることです。私は実際にこれをより頻繁に目にしてきました。
関連
-
[解決済み] SQL Serverで実行中の合計を計算する
-
[解決済み] MySQLの「スキーマの作成」と「データベースの作成」 - 違いはあるのか?
-
[解決済み] アドホッククエリとは何ですか?
-
[解決済み] SQL Server - 挿入された行のIDを取得するための最良の方法は?
-
[解決済み] SQL Serverでシングルクォートをエスケープするにはどうすればよいですか?
-
[解決済み] PostgreSQLからのPL/pgSQL出力をCSVファイルに保存する
-
[解決済み] SQL ServerでJOINを使用してテーブルを更新しますか?
-
[解決済み] SQL ServerにおけるINSERT OR UPDATEに関する解決策
-
[解決済み】「INNER JOIN」と「OUTER JOIN」の違いは何ですか?
-
[解決済み] MySQL JOINは最新行のみ?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
解決策:java.sql.SQLException: ユーザー ''@'localhost'' (パスワード: YES を使用) のアクセスが拒否されました。
-
windows mysql prompt access denied for user ''@'localhost' to database.
-
executeQuery()ソリューションでデータ操作文を発行できない。
-
[解決済み] Oracle Trigger ORA-04098: トリガーが無効で、再バリデーションに失敗しました。
-
[解決済み] 各GROUP BYグループの最初の行を選択しますか?
-
[解決済み] 複数の列でgroup byを使用する
-
[解決済み] SQL Serverには、.NETのMath.Maxのような2つの値を取るMax関数はありますか?
-
[解決済み] SQL Server 2008を使用してIDENTITY_INSERTをオン/オフする方法は?
-
[解決済み] Selectステートメントで特定のフィールドの重複を検索する
-
[解決済み] 別のテーブルに一致する項目がない行を選択するにはどうすればよいですか?