PR

 この特集の目的は,SQL文の処理手続きの問題点を見抜けるようになることです。そのために,SQL文ごとに最適と思われる処理手続きを解説しています。前回までは一つのテーブルを検索処理対象にしていましたが,今回から,一つのSQL文で二つのテーブルを検索対象にするケースを説明します。

二つ目のサンプル・テーブル

 二つのテーブルを対象にしますので,これまでの特集で説明してきた[顧客]テーブル(表1)のほかに,[販売]テーブル(表2)を追加します。[販売]テーブルのカラムは,[販売番号](整数),[販売日](日付),[商品コード](整数,4ケタ),[数量](整数),[顧客番号](整数,4ケタ)――の五つあります。[販売]テーブルには“誰に”“何を”“いつ”“何個”販売したかというデータを格納している,と想定してください。

表1●[顧客]テーブルの定義
表1●[顧客]テーブルの定義

表2●[販売]テーブルの定義
表2●[販売]テーブルの定義

 そのうち“誰”に当たる部分が[顧客番号]で,それは[顧客]テーブルに格納している[顧客番号]に依存しています。依存しているというのは,[販売]テーブルの[顧客番号]の値は,[顧客]テーブルの[顧客番号]に存在する,ということです。[販売]テーブルのデータだけでは“誰”の情報は[顧客番号]という数値でしか分かりませんが,その数値を基に[顧客]テーブルを検索すれば,顧客名や性別,年齢,地域などが分かるようになります。

 [顧客]テーブルは30レコードで,その一部を表3に示します。一方の[販売]テーブルは1000レコードあるとします。その一部を表4に示しました。どちらにもインデックスは付いていないとします。

表3●[顧客]テーブルのカラム値
表3●[顧客]テーブルのカラム値
性別は,0=男性,1=女性

表4●[販売]テーブルのカラム値
表4●[販売]テーブルのカラム値

 テーブルの説明を終えたところで,この二つのテーブルを検索対象にするSQL文を示しましょう。

SELECT 販売日,顧客名,商品コード,数量 FROM 顧客,販売 WHERE 顧客.顧客番号 = 販売.顧客番号 AND 顧客.顧客名 = '清水香織'

意味:[顧客]テーブルの[顧客番号]と,[販売]テーブルの[顧客番号]が同じ値であるという条件で[顧客]テーブルと[販売]テーブルを結合し,[顧客名]の値が「清水香織」である,[販売日][顧客名][商品コード][数量]を抽出

 意味が長くなってしまいましたので,ポイントとなる点を説明します。

SELECT 販売日,顧客名,商品コード,数量

の部分は,抽出するカラムを指定しています。注目したいのは[顧客]テーブルと[販売]テーブルの両方のカラムが含まれていることです。両方のテーブルを検索しないと結果を得ることはできません。そのために,RDBMSでは「ジョイン(結合)」という手法を用います。

 ジョインについてはこの後,詳しく説明しますが,ここでは二つのテーブルをくっつけて一つのテーブルにすること,と考えてください。

WHERE 顧客.顧客番号 = 販売.顧客番号 AND 顧客.顧客名 = '清水香織'

のうち,「顧客.顧客番号 = 販売.顧客番号」の部分が先ほど説明したジョインの条件に当たります。この条件に基づいて作られた一つのテーブルに対し,「顧客名 = '清水香織'」の条件に合うレコードを抽出する,という意味になります。

ジョインとは配列の直積のこと

 このSQL文の処理手続きを説明しますが,その前にどうしても説明しておきたいことがあります。それは,「ジョインとはどういうことなのか」ということです(図1)。多少抽象的になりますが,ジョインをきちんと理解するには避けては通れないポイントですので,少しお付き合いください。

図1●これがジョイン
図1●これがジョイン
テーブルを配列とし,配列の直積を取ること((1)から(2)を作ること)がジョインである。たいていのSQL文ではジョインに条件が伴うので,(2)の一部のみを抽出することになる((3))

 [A]と[B]の二つのカラムを持つテーブルと,[C]と[D]の二つのカラムを持つテーブルのジョインを考えます(図1(1))。ジョインは二つのテーブルを結合することですが,テーブルとテーブルを結合するというのは,配列の直積を行うことです。配列の直積を行うと,図1(2)のようになります。これがジョインです。

 ジョインにより一つの大きなテーブルが作られました。ですが実際のSQL文の処理では,(2)のようなテーブルが作成されることはまずありません。実際のSQL文にはジョインの条件があり,(2)のテーブルの一部だけが作られます。図1(3)では[A]カラムと[C]カラムが等しいという条件であった場合を示しています。a1=1,a2=2,a3=3,c1=1,c2=2だとすると,[A]と[C]が等しいという条件ですので,(2)のテーブルのレコードのなかで「a1 b1 c1 d1」と「a2 b2 c2 d2」の二つのレコードだけが該当することになります。

監修:藤塚 勤也(ふじづか きんや) NTTデータ 基盤システム事業本部 オープンソース開発センタ 技術開発担当 シニアスペシャリスト
沖電気工業,タンデムコンピューターズ(現日本HP)を経て,2003年より株式会社 NTTデータに勤務。現在は,オープンソース・ソフトウエアを活用したエンタープライズ・システム向けの技術開発・技術支援に従事しており,特にシステムの中核であるRDBMSに注力している。「RDBMS解剖学」(翔泳社)を共著