【SQLite3】JOIN句で外部結合(outer join)する方法

サーバ・DBなどのイメージズを作成している

結合にはいくつか種類があります。当ブログでまず取り上げるのは、内部結合と外部結合、そして自己結合です。

内部結合は、2つのテーブルで結合対象の列を指定し、一致しているレコード同士のみを結合して取得する処理。でした。

結合の際、一致していないレコードは無視され、結合から除外されてしまいます。

サーバ・DBなどのイメージズを作成している

【SQLite3】JOIN句で内部結合(inner join)する方法

2022年11月28日

しかし、それでは困る場合があります。

集計をしたときに一致していないレコードであっても結果表に出力してほしい場合は、内部結合では実現することができません。

そこで、外部結合の出番です。

記事要約
  1. 外部結合について解説します。
  2. SQLite3は、LEFT JOINのみサポートしています。
  3. サンプルと動作結果

目次

外部結合とは何か?

2つのテーブルを結合する際、指定したテーブルの列の値が一致するレコードだけでなく、どちらかのテーブルにのみレコードが存在する場合も合わせて取得する方法。です。

外部結合の種類

【前提】両方のテーブルに存在するレコードを、結果表に出力することに加えて、以下の動作を実行。

  • 左外部結合:左側のテーブルにしかないレコードも取得する。
  • 右外部結合:右側のテーブルにしかないレコードも取得する。
  • 完全外部結合:左側のテーブルにしかないレコードと右側のテーブルにしかないレコードも取得する。

注意点①(SQLite3のサポート範囲:左外部結合のみ)

SQLite3では、左外部結合のみサポートしています。

もし、SQLiteで右外部結合を実行した場合は、以下のようなエラーが返ってきます。

Parse error: RIGHT and FULL OUTER JOINs are not currently supported

注意点②(外部結合・内部結合で集計結果の差異)

内部結合と外部結合それぞれで一長一短があります。

使用する差異注意しなければならないことが、主に2点あります。

結合利用上の注意点
  1. 外部結合と内部結合でレコードの数が異なります。
  2. 外部結合は、内部結合に比べ結果表を作成するために時間がかかります。

外部結合は、一致するIDが存在しなかった場合は、強制的にNullのレコードを作成し結合します。

その分、レコード数が増えます。

そうしたときに①の注意点が発生します。

レコード数の集計をしたときに、外部結合したテーブルはレコード数が増えるので注意が必要です。

また、レコードが増える分、外部結合の方が処理が重くなります。

イメージ(左外部結合)

基本構文とサンプル

基本構文(左外部結合)

select * from テーブル名称(左表) left join テーブル名称(右表) on listed_MARKET = mk_id;

サンプルコード

禄太
listedmarketテーブルに銘柄を追加します。
【上場市場:90】【上場市場:Null】と言う銘柄です。
どちらも、marketテーブルには存在しない市場です。
#データ追加
insert into listedmarket(MEI_CD,listed_MARKET) values(1000,90);
insert into listedmarket(MEI_CD,listed_MARKET) values(2000,NULL);
#左外部結合
select * from listedmarket left join market on listed_MARKET = mk_id;

実行結果(画面)

禄太
Nullのレコードが生成されて、IDが一致していないレコードも消されずに結合処理されています。

おまけサンプル(右外部結合・完全外部結合)

#右外部結合(右側のレコードをすべて出力する)
select * from テーブル名称(左表) right join テーブル名称(右表) on (結合条件);

#完全外部結合(左右両方のレコードをすべて出力する)
select * from テーブル名称(左表) full join テーブル名称(右表) on (結合条件);

おまけ(イメージ:右外部結合)

禄太
せっかく作ったので、載せてみました!

EOF

外部結合についてまとめました。

内部結合とあわせて、ご参照ください。

できるようになったら、きっと強い味方になってくれます。

禄太
本日も一緒に学習してくださって、ありがとうございました!

では、また次回!