LEFT JOIN / INNER JOIN を実行すると同じ内容のレコードが複数含まれる
JOIN を実行すると同じ内容のレコードが複数含まれる現象について紹介します。
例
下記のテーブルを準備します。
Working テーブル
id | name | value | category | memo |
1 | Penguin | 300 | B | 南国にすむペンギンです |
2 | Whale | 420 | M | 北極海のクジラです |
3 | Moffu | 880 | NULL | よくわからない生き物です |
4 | Camel | 220 | M | 砂漠にすむラクダです |
5 | Owl | 90 | B | 関東のフクロウです |
6 | Duck | 120 | B | そこらへんのアヒルです |
WorkingCategory テーブル
id | category | name | flag |
1 | B | 鳥類 | 1 |
2 | B | 鳥類 | 2 |
3 | M | 哺乳類 | 1 |
下記のSQLを実行します。
select Working.name, Working.category, WorkingCategory.name from Working
left join WorkingCategory on Working.category=WorkingCategory.category;
下記の結果となります。
name | category | name |
Penguin | B | 鳥類 |
Penguin | B | 鳥類 |
Whale | M | 哺乳類 |
Moffu | NULL | NULL |
Camel | M | 哺乳類 |
Owl | B | 鳥類 |
Owl | B | 鳥類 |
Duck | B | 鳥類 |
Duck | B | 鳥類 |
category の値がBのレコードは同じ内容のレコードが2つ含まれています。これは、WorkingCategory テーブルにcategoryの値が"B"で、flagの値が"1"と"2"のレコードの2種類があるため、それぞれが結合された結果2つの同じ値のレコードが出力されます。
inner joinを実行した場合もレコードは重複します。
select Working.name, Working.category, WorkingCategory.name from Working
inner join WorkingCategory on Working.category=WorkingCategory.category;
name | category | name |
Penguin | B | 鳥類 |
Penguin | B | 鳥類 |
Whale | M | 哺乳類 |
Camel | M | 哺乳類 |
Owl | B | 鳥類 |
Owl | B | 鳥類 |
Duck | B | 鳥類 |
Duck | B | 鳥類 |
対処方法:distinct を利用
出力されるフィールドの値が全く同じ場合は distinct を利用すると回避できます。
下記のSQL文を実行します。
select distinct Working.name, Working.category, WorkingCategory.name from Working
left join WorkingCategory on Working.category=WorkingCategory.category;
結果は以下になります。
name | category | name |
Camel | M | 哺乳類 |
Duck | B | 鳥類 |
Moffu | NULL | NULL |
Owl | B | 鳥類 |
Penguin | B | 鳥類 |
Whale | M | 哺乳類 |
inner joinの場合は下記です。
select distinct Working.name, Working.category, WorkingCategory.name from Working
inner join WorkingCategory on Working.category=WorkingCategory.category;
結果は以下になります。
name | category | name |
Camel | M | 哺乳類 |
Duck | B | 鳥類 |
Owl | B | 鳥類 |
Penguin | B | 鳥類 |
Whale | M | 哺乳類 |
distinct文の詳細については
こちらの記事を参照してください。
対処方法:条件を追加
条件で絞り込むことで、結合するレコードが1つになる場合は、結合条件を追加することで回避できます。on節の条件式に and を記述することで複数の条件を結合条件に設定できます。
今回の例の場合WorkingCategory テーブルのflagが1の場合に限り結合すれば、結合するレコードを1つにできます。下記のSQL文実行します。
select Working.name, Working.category, WorkingCategory.name from Working
left join WorkingCategory on Working.category=WorkingCategory.category and WorkingCategory.flag=1;
結果は以下になります。
name | category | name |
Penguin | B | 鳥類 |
Whale | M | 哺乳類 |
Moffu | NULL | NULL |
Camel | M | 哺乳類 |
Owl | B | 鳥類 |
Duck | B | 鳥類 |
このページのキーワード
- LEFT JOIN 同じレコード 複数
- INNER JOIN 同じレコード 複数
著者
iPentec.com の代表。ハードウェア、サーバー投資、管理などを担当。
Office 365やデータベースの記事なども担当。