はじめに
SQLを使っていて、結合(join)という演算を使わないことはありません。リレーショナルデータベースでは、設計のセオリーとして正規化というプロセスを踏む場合が多いため、必然的にテーブルの数は複数になります。そうすると、複数のテーブルに散在するデータを統―いわば「逆正規化」―したり、あるいは結果として得たいデータのフォーマットを作るために、私たちはさまざまな種類の結合を利用します。
結合演算は、SQLの演算の中では比較的イメージをつかみやすいものです(少なくとも、相関サブクエリとかCASE式に比べれば)。しかし他方、結合は種類のバリエーションがかなり多く、どういう場合にどういう結合を使うのが適切なのか、迷うことも少なくありません。本稿では、SQLで利用される結合について、どのような種類の結合がどういう動作を行うか、理論的な整理を行いたいと思います[1]。そして、結合という演算を集合指向的な観点からとらえなおし、どのような意味を持っているかを明らかにします。
- 読者対象
- 結合の構文は理解している人
- 内部結合と外部結合が、いったい何の「内」と「外」なのかわからない人
- 結合の種類が多過ぎて整理がつかない人
- 稼働環境
クロス結合~すべての結合の母体
クロス結合とは
結合について話をするにあたり、まずクロス結合(cross join)から始めたいと思います。このクロス結合は、実務で使う機会はほとんどありません。中にはこれまで1回も使ったことがないとか、そもそも存在を知らなかった、という人だっているかもしれません。それをあえて最初に解説するのは、SQLにおける結合という演算を理解するには、クロス結合を理解してもらうことが一番の近道だからです(理由は次の内部結合と外部結合の節を読むとわかります)。
サンプルに使うのは図1のような簡単なテーブルです。社員およびその所属部署を管理するものです。この2つのテーブルに対してクロス結合を行う構文は、リスト1のようになります。
図1 クロス結合を行うサンプルのテーブル
社員テーブル(Employees)
emp_id (社員ID) | emp_name (社員名) | dept_id (部署ID) |
001 | 石田 | 10 |
002 | 小笠原 | 11 |
003 | 夏目 | 11 |
004 | 米田 | 12 |
005 | 釜本 | 12 |
006 | 岩瀬 | 12 |
部署テーブル(Departments)
dept_id (部署ID) | dept_name (部署名) |
10 | 総務 |
11 | 人事 |
12 | 開発 |
13 | 営業 |
リスト1 クロス結合を実行
SELECT *
FROM Employees CROSS JOIN Departments;
さて、それでは最初の質問です。この結果の行数は何行でしょう? 計算方法を知っているかどうかだけが問題ですので、あまり考えずに即答してください。
正解は24行。計算方法は、社員テーブルの行数6と、部署テーブルの行数4の掛け算です。結果を全部表示するとちょっと多いのですが、図2のようになります。
図2 リスト1の実行結果
EMP_ID EMP_NAME DEPT_ID DEPT_ID DEPT_NAME
------ -------- ------- ------- ---------
001 石田 10 10 総務
001 石田 10 11 人事
001 石田 10 12 開発
001 石田 10 13 営業
002 小笠原 11 10 総務
002 小笠原 11 11 人事
002 小笠原 11 12 開発
002 小笠原 11 13 営業
003 夏目 11 10 総務
003 夏目 11 11 人事
003 夏目 11 12 開発
003 夏目 11 13 営業
004 米田 12 10 総務
004 米田 12 11 人事
004 米田 12 12 開発
004 米田 12 13 営業
005 釜本 12 10 総務
005 釜本 12 11 人事
005 釜本 12 12 開発
005 釜本 12 13 営業
006 岩瀬 12 10 総務
006 岩瀬 12 11 人事
006 岩瀬 12 12 開発
006 岩瀬 12 13 営業
クロス結合は、数学的には直積とかデカルト積と呼ばれる演算で、結合対象となる2つのテーブルのレコードから、可能な組み合わせすべてを網羅する演算です。したがって、社員テーブル1行に対して部署テーブル4行が結合されるため、結果的には6×4=24行になるわけです。
クロス結合が実務で使われない理由
クロス結合を実務で意識することがほとんどない理由は、2つあります。
- 実際にこういう結果を求めたいケースがない
- 非常にコストがかかる演算である
クロス結合は、その結果行数の多さからも想像がつくように、数ある結合演算の中で最も高コストです。
ではそんな、ある意味でマイナーな結合を何で最初に解説するのでしょうか? それは先述のとおり、この演算がほかのすべての結合演算の母体だからです。論より証拠、次へ進みましょう。