はじめに
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 | 営業 |
さて、それでは最初の質問です。この結果の行数は何行でしょう? 計算方法を知っているかどうかだけが問題ですので、あまり考えずに即答してください。
正解は24行。計算方法は、社員テーブルの行数6と、部署テーブルの行数4の掛け算です。結果を全部表示するとちょっと多いのですが、図2のようになります。
クロス結合は、数学的には直積とかデカルト積と呼ばれる演算で、結合対象となる2つのテーブルのレコードから、可能な組み合わせすべてを網羅する演算です。したがって、社員テーブル1行に対して部署テーブル4行が結合されるため、結果的には6×4=24行になるわけです。
クロス結合が実務で使われない理由
クロス結合を実務で意識することがほとんどない理由は、2つあります。
- 実際にこういう結果を求めたいケースがない
- 非常にコストがかかる演算である
クロス結合は、その結果行数の多さからも想像がつくように、数ある結合演算の中で最も高コストです。
ではそんな、ある意味でマイナーな結合を何で最初に解説するのでしょうか? それは先述のとおり、この演算がほかのすべての結合演算の母体だからです。論より証拠、次へ進みましょう。