プログラミングマガジン

プログラミングを中心にIT技術をできるだけわかりやすくまとめます。

  • ホーム
  • データベース
  • 【SQL】結合について
 
 
     
  • サーバー言語  
    • Python
    • Ruby
    • PHP
    • SQL
  •  
  • インフラ  
       
    • AWS
    •  
    • 基本
    • Git
  • Web
       
    • Web開発
    • JavaScript
    • Vue.js
    • React
  •  
  • 設計  
       
    • 実装設計
    • DB設計
  • 問い合わせ
  

【SQL】結合について

04.29

  • miyabisan2
  • コメントを書く

この記事は3分で読めます

結合とは?

正規化されて、分割されたテーブル同士に対して、結合条件が満たされた行を1行ずつつないで一つの非正規形の表にすること。

結合の動作の仕組み

結合元のテーブルの値を結合条件にして、1行ずつ結合先のテーブルの行で結合条件に合うものがないか探していく仕組みになっています。

しかし、動作の仕組み的に、下記のように様々なケースが考えられるでしょう。

ケース1:重複があった場合の結合は?

結合先のテーブルの、結合条件の値に重複があった場合は、結合元のテーブルの行を結合先の重複件数に合うように複製されてしまいます。

なので、結合結果が、元のテーブルの行数より増えてしまいます。

対策

対策としては、テーブルの設計段階(論理設計時に考える。)で、「多:多」の関係を作らないことです。

テーブル設計の基本的な流れについては、下記の記事で解説していますので、ご覧下さい。

【データベース設計】基本的な流れ

ケース2:結合条件に合致する項目がない場合は?

逆に、結合先に結合条件に合致する項目がなかった場合は、結合結果が、元のテーブルの行数よりも減ってしまいます。

対策

結合結果として、相手先が見つからなかった場合に、行数が減ってしまうのは問題があります。

対策1:外部結合を使う

対策として「外部結合」を使うパターンがあります。

「外部結合」であれば、相手先が見つからなかったとしても、NULLとして結果を返してくれるので、行数が減ることがありません。

対策2:外部キーを使う

「外部キー」を使えば、DBMSがシステム的に、親テーブルに存在しない値が入力されるのを防いでくれます。

ただ、外部キーにも、メリット、デメリットありますので、下記の記事を参考にされて下さい。

【データベース】「外部キー」、「リレーション」について

通常の内部結合

下記の構文を使います。

1
2
3
4
SELECT 選択列
FROM テーブルA
JOIN テーブルB
ON 結合条件

JOINを使わない内部結合

RDBMSによっては、下記のようにJOIN句を使わずに、内部結合を記述することができます。

1
2
3
SELECT 選択列
FROM テーブルA,テーブルB
WHERE 結合条件

標準SQLでも定義されていて、特に年配プログラマが書かれたSQL文では未だにこうした記述をされているケースは少なくありません。

しかし、この記述方法は、以下理由によりあまり推奨されないです。

  • 結合元のテーブルがわかりずらい。
  • WHERE句に、結合条件だけでなく、絞込み条件も記述するため、どれが結合条件で、どれが絞り込み条件なのか判別がしずらい。
  • 構文自体が古い構文と認定されつつあるので、いずれこの構文が使われなくなりえます。

特に古くから作られたシステムではそうですが、現場でも良く見かける内部結合の記述方法なので、新規では書かなくてよいですが、最低限知識として持っておき読めるようにしておきましょう。

なお、WHERE句を使わなかった場合は、「クロス結合(CROSS JOIN)」をした結果と同じになります。内部結合をしたい場合は、必ずWHERE句で結合条件を指定する必要があります。

外部結合

左外部結合

構文

1
2
3
4
SELECT 選択列
FROM テーブルA(左表)
LEFT JOIN テーブルB(右表)
ON 結合条件

特徴

左表のデータを必ず残す。

右外部結合

構文

1
2
3
4
SELECT 選択列
FROM テーブルA(左表)
RIGHT JOIN テーブルB(右表)
ON 結合条件

特徴

右表のデータを必ず残す。

「左外部結合(LEFT JOIN)」と「右外部結合(RIGHT JOIN)」をどのように使い分けるか?

基本的には、どちらの結合も機能的な差はありません。

一般的には、先にマスタとなるテーブルが出てくる「LEFT JOIN」を使うケースが多いようですが、LEFT JOINを使わなければならないという明確な理由はありません。

完全外部結合

構文

1
2
3
4
SELECT 選択列
FROM テーブルA(左表)
FULL JOIN テーブルB(右表)
ON 結合条件

特徴

両方の表データを必ず残す。

外部結合の例

テストデータ

USER_MASTER
USER_ID DEPT_NO USER_NAME
21 1002 小泉 純子
22 1003 小泉 三郎
23 1004 小泉 花子
20 1001 小泉 純一
AUTHORIZATION
USER_ID LOGIN_ID PASSWD
21 10002 234567
20 10001 1234567

左外部結合

LEFT JOINを使う場合

1
2
3
SELECT * FROM USER_MASTER u
LEFT JOIN AUTHORIZATION a
ON u.USER_ID = a.USER_ID

少し古い書き方

条件に「(+)」を付けた方のテーブルを基準にデータを残します。

1
2
select * from user_master u,authorization a
where u.USER_ID = a.USER_ID(+)

実行結果
USER_ID DEPT_NO USER_NAME USER_ID LOGIN_ID PASSWD
21 1002 小泉 純子 21 10002 234567
20 1001 小泉 純一 20 10001 1234567
23 1004 小泉 花子 NULL NULL NULL
22 1003 小泉 三郎 NULL NULL NULL

LEFT JOIN決め打ちルールについて

LEFT JOINにON句を使って抽出をすればINNER JOINと同じように使うこともできます。なので、開発現場によっては「LEFT JOINのみを使うこと」とルールを決めている現場もあるようです。

ただ、これは以下の理由によりあまり良くありません。

NULLが入る

なぜならLEFT JOINはカラムにNULLが入る可能性があるためです。カラムにNULLが入ると必然的に思わぬバグが発生する可能性が上がります。

無意味なWHERE句操作が入る場合がある。

そもそも、INNER JOINを使っていればLEFT JOINしてからのちに条件を抽出するという操作は不要になる場合が多いです。無意味な操作をしいられることになりパフォーマンスに影響が出てしまいます。

クロス結合(CROSS JOIN)

この結合は、結論から申しますと、実務で扱うことはほぼないです。

集合で言えば、「直積」になるので、大量の行数が出てきます。

パフォーマンスを意識した結合

少し、SQL上級者向けになりますが、結合処理は非常に負荷がかかる処理です。

パフォーマンスを意識した結合についても考慮できるようにしましょう。詳しくは、下記の記事で解説しています。

【SQL】パフォーマンスを考えるに当たり必要な「結合」の知識(Oracle)

スポンサーリンク
  • 2018 04.29
  • miyabisan2
  • コメントを書く
  • SQL, データベース
  • Tweets Twitter
  • このエントリーをはてなブックマークに追加
  • LINEで送る

関連記事

  1. 2018 04.22

    【データベース設計】インデックス(索引)の基本

  2. 2018 04.24

    【データベース設計】ビューの基本

  3. 2018 05.20

    【PL/SQL】条件分岐

  4. 2018 06.21

    【SQL】「DELETE文」と「TRUNCATE文」の違い

  5. 2021 09.26

    【SQL】「JOIN」と「パフォーマンス」について

  6. 2018 04.25

    【データベース設計】採番について

  • コメント ( 0 )
  • トラックバック ( 0 )
  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。

返信をキャンセルする。

【データベース】ロックの基礎知識(デッドロック等も)

【システム開発】開発モデル、開発手法の種類

RETURN TOP

著者プロフィール

エンジニア歴10年で過去に業務系、Webデザイン、インフラ系なども経験あります。現在はWeb系でフロントエンド開発中心です。

詳細なプロフィールはこちら

スポンサーリンク

カテゴリー

  • Android
  • AngularJS
  • API
  • AWS
  • C++
  • CSS
  • cursor
  • C言語
  • DDD
  • DevOps
  • Django
  • Docker
  • Figma
  • Git
  • GitLab
  • GraphQL
  • gRPC
  • Hasura
  • Java
  • JavaScript
  • Kubernetes
  • Laravel
  • linux
  • MySQL
  • Next.js
  • nginx
  • Node.js
  • NoSQL
  • Nuxt.js
  • Oracle
  • PHP
  • Python
  • React
  • Redux
  • Rspec
  • Ruby
  • Ruby on Rails
  • Sass
  • Spring Framework
  • SQL
  • TypeScript
  • Unity
  • Vue.js
  • Webサービス開発
  • Webデザイン
  • Web技術
  • インフラ
  • オブジェクト指向
  • システム開発
  • セキュリティ
  • その他
  • データベース
  • デザインパターン
  • テスト
  • ネットワーク
  • プログラミング全般
  • マイクロサービス
  • マイクロソフト系技術
  • マルチメディア
  • リファクタリング
  • 副業
  • 未分類
  • 業務知識
  • 生成AI
  • 設計
  • 関数型言語
RETURN TOP

Copyright ©  プログラミングマガジン | プライバシーポリシー