🧚 お知らせ!Beekeeper Studio は高速でモダンなオープンソースのデータベース GUI です ダウンロード
2024年1月2日 著者: Matthew Rathbone

SQL を理解するうえで大切なのは、適切な問いを立てることです。複数のテーブルにまたがるデータを扱う場合、フルアウタージョインは間違いなく便利な操作です。一部のデータベース管理システムではごく一般的ですが、MySQL では FULL OUTER JOIN の扱いが少し厄介です。なぜでしょうか?標準ではサポートされていないからです。興味深いですよね?でもご安心ください、回避策があります!

このチュートリアルでは、MySQL でフルアウタージョインを実装する方法を詳しく見ていきます。準備はいいですか?たくさんのコード例に飛び込んでいきましょう。

🔖 クイックリファレンス: すべての JOIN の種類をすぐに確認したいですか?図解とコード例を掲載した SQL JOIN チートシートをご覧ください。

Full Outer Join とは?

始める前に、FULL OUTER JOIN とは何かを定義しておきましょう。SQL におけるフルアウタージョインは、左外部結合と右外部結合の両方を適用した効果を組み合わせたものです。つまり、両方のテーブルで値が一致するレコードに加えて、もう一方のテーブルに一致する値がない両テーブルのすべてのレコードも取得します。

Full Outer Join の図解

例を見てみましょう。Employees と Departments という 2 つのテーブルがあるとします。

Employees テーブル:

id name
1 Alice
2 Bob
3 Charlie

Departments テーブル:

id department
2 HR
3 IT
4 Marketing

FULL OUTER JOIN クエリを使用すると:

SELECT * FROM Employees
FULL OUTER JOIN Departments ON Employees.id = Departments.id;

結果セットは次のようになります:

Employees.id Employees.name Departments.id Departments.department
1 Alice NULL NULL
2 Bob 2 HR
3 Charlie 3 IT
NULL NULL 4 Marketing

この出力は、Employees と Departments の両方のすべてのレコードを組み合わせたものです。含まれるのは次のとおりです:

  • 両方のテーブルで id の値が一致するレコード(Bob と Charlie)。
  • Departments に対応するレコードがない Employees のレコード(Alice)。
  • Employees に対応するレコードがない Departments のレコード(Marketing)。

非常に便利な構文ですが、MySQL では直接サポートされていません。では、どうすればよいのでしょうか?見ていきましょう。

MySQL で Full Outer Join を再現する

前述のとおり、MySQL は FULL OUTER JOIN キーワードを明示的にはサポートしていません。しかし、LEFT JOIN と UNION を組み合わせることで、同じ出力を得ることができます

MySQL でフルアウタージョインを再現する考え方は、次の 2 つのステップから成ります:

  • 1 つ目のテーブルに対して LEFT JOIN を実行し、1 つ目のテーブルのすべてのレコードと、2 つ目のテーブルの一致するレコードを取得します。
  • UNION を使って、その結果を RIGHT JOIN の結果と組み合わせ、2 つ目のテーブルのすべてのレコードと、1 つ目のテーブルの一致するレコードを取得します。

それぞれの要素の仕組みは次のとおりです:

Left Join:
Left Join の図解

Right Join:
Right Join の図解

MySQL の Full Outer Join の例

先ほどと同じデータを使った回避策の例を示します

SELECT 
    Employees.id AS Employees_id, 
    Employees.name, 
    Departments.id AS Departments_id, 
    Departments.department
FROM 
    Employees
LEFT JOIN 
    Departments ON Employees.id = Departments.id

UNION

SELECT 
    Employees.id AS Employees_id, 
    Employees.name, 
    Departments.id AS Departments_id, 
    Departments.department
FROM 
    Departments
RIGHT JOIN 
    Employees ON Departments.id = Employees.id;

このクエリは 2 つの部分で構成されています:

  1. LEFT JOIN で、Employees テーブルのすべてのレコードと、Departments テーブルの一致するレコードを取得します。
  2. RIGHT JOIN で、Departments テーブルのすべてのレコードと、Employees テーブルの一致するレコードを取得します。

UNION は、重複する行を除外しながらこの 2 つのクエリの結果を結合します。

同じサンプルテーブルの場合、結果セットは次のようになります:

Employees_id name Departments_id department
1 Alice NULL NULL
2 Bob 2 HR
3 Charlie 3 IT
NULL NULL 4 Marketing

この出力は、SQL の FULL OUTER JOIN と同様に、Employees と Departments の両方のすべてのレコードを組み合わせたものです。

UNION は重複を自動的に除外する

Employees テーブルと Departments テーブルを使った今回の例では、MySQL で FULL OUTER JOIN を再現する回避策に使った UNION によって重複が生じることはありません。UNION 演算子は、結果セットから重複する行を自動的に除外するためです。

わかりやすくするために、この場合に UNION がどのように動作するかを考えてみましょう:

  • クエリの前半(LEFT JOIN)は、Employees テーブルのすべてのレコードと、Departments テーブルの一致するレコードを取得します。これには、両方のテーブルで id の値が一致する行と、Departments に一致するものがない Employees の行が含まれます。

  • クエリの後半(RIGHT JOIN)は、Departments テーブルのすべてのレコードと、Employees テーブルの一致するレコードを取得します。これには、両方のテーブルで id の値が一致する行と、Employees に一致するものがない Departments の行が含まれます。

UNION は重複を取り除くため、id の値が一致する行(LEFT JOIN と RIGHT JOIN の両方の結果に現れる行)は、最終結果に一度だけ表示されます。

まとめると、この場合に UNION を使うことで、Employees と Departments のデータの一意な組み合わせが結果セットに一度だけ現れるようになり、重複のない FULL OUTER JOIN の動作を再現できます。

Beekeeper Studio で練習しよう

この MySQL フルアウタージョインのチュートリアルがお役に立てば幸いです。今後の記事でも、MySQL のその他の高度な機能を取り上げ、さらに多くのコード例を紹介しながら、それらの機能がなぜ、どのように動作するのかを深く掘り下げていきます。それまでは、ぜひ Beekeeper Studio を使って SQL スキルを磨き続けてください。

Beekeeper Studioは無料のオープンソースのデータベースGUIです

これまで使った中で最高のSQLクエリ&エディタツールです。データベースの管理に必要なものがすべて揃っています。 - ⭐⭐⭐⭐⭐ Mit

Beekeeper Studioは高速で直感的、そして使いやすいツールです。多数のデータベースに対応し、Windows、Mac、Linuxで快適に動作します。

BeekeeperのLinux版は100%フル機能。手抜きも機能の妥協も一切ありません。

Beekeeper Studio 利用者の声

★★★★★
「Beekeeper Studio で以前の SQL ワークフローを完全に置き換えました。高速で直感的で、データベース作業がまた楽しくなりました。」
— Alex K.、データベース開発者
★★★★★
「多くのデータベース GUI を試してきましたが、Beekeeper は機能とシンプルさのバランスが絶妙です。とにかくちゃんと動きます。」
— Sarah M.、フルスタックエンジニア