ITの教科書検索
入門読了 約10分

関係演算とは ― 選択・射影・結合の違い

関係演算は、表から新しい表を作る操作で、SQLのSELECT文のもとになる考え方です。選択・射影・結合・直積・商と、和・差・積の違いを、図で結果の表を比べて確かめられます。

目次
  1. 関係演算とは
  2. 選択と射影の違い
  3. 結合(等結合と自然結合)
  4. 直積と商
  5. 和・差・積の集合演算
  6. 演算を選んで結果を比べる
  7. 練習問題

関係演算とは、表から新しい表を作る操作

関係演算とは、関係データベースの表を入力にして、新しい表を結果として返す操作です。代表的なものに、行を取り出す選択、列を取り出す射影、2つの表をつなぐ結合があります。結果も表なので、ある演算の結果に別の演算を続けてかけられます。

SQLのSELECT文の句の多くは、この演算に当たります。WHERE句は選択、SELECTの直後に並べる列名は射影、JOINは結合です。どの句がどの演算かが分かると、長いSQLも句ごとに分けて読めます。

RDBの表を数学の関係として扱う考え方は、1970年にE. F. Coddが論文で示しました。Coddは1972年の論文で、これらの演算をまとめた体系を関係代数と呼んでいます。選択・射影・結合・商・直積を関係演算、和・差・積を集合演算と分けて呼びます。

8つの演算と、SQLで近い書き方
演算することSQLで近い書き方
選択条件に合う行を取り出すWHERE
射影指定した列を取り出すSELECT DISTINCT 列名
結合共通の列で2つの表をつなぐJOIN
直積2つの表の行をすべて組み合わせるCROSS JOIN
商相手の表の値をすべて持つものを求める1語では書けない
和どちらかの表にある行を集めるUNION
差一方の表にだけある行を残すEXCEPT
積両方の表にある行を残すINTERSECT

例には、社員表と部署表のような小さな表を使います。SQLの書き方はSELECT文の記事に、表をつなぐ書き方はJOINの記事にまとめました。

選択は行を、射影は列を取り出す

選択は表を横に切り、射影は表を縦に切ります。選択は、部署IDがD1の行のように、条件に合う行だけを残します。射影は、部署IDの列のように、指定した列だけを残します。Coddの1972年の論文では、選択に当たる演算を制限と呼んでいます。

選択:行を選ぶ氏名部署ID田中D1残る佐藤D2消える鈴木D1残る高橋D2消える射影:列を選ぶ氏名部署ID田中D1佐藤D2鈴木D1高橋D2部署IDD1D2重複を除く
選択は条件に合う行を横に切り出し、射影は指定した列を縦に切り出します。射影ではD1とD2が2回ずつ出ますが、結果の表では重複が除かれて2行になります。

射影の結果では、同じ値の行が1つにまとまります。Coddの論文は、列を選んだあとに行の重複を除いたものを射影と定めています。図の社員表で部署IDの列だけを取り出すと、4行ではなくD1とD2の2行になります。

SQLとの対応では、名前が重なっていることに注意が必要です。条件で行を絞る選択は、WHERE句に当たります。SELECTの直後に列名を並べる部分は、選択ではなく射影に当たります。

SQLのSELECTは、何も指定しないと重複した行も全部残します。関係演算の射影と同じ結果にするには、SELECT DISTINCTと書いて重複を除きます。

結合は共通の列で2つの表をつなぐ

結合は、2つの表に共通する列の値をもとに、行どうしをつないで1つの表にします。社員表と部署表なら、部署IDが等しい行どうしをつなぐと、社員ごとの部署名が分かります。このように列の値が等しいことを条件にする結合を、等結合と呼びます。比べ方を等号に限らず、<や≠なども使えるように広げた結合は、θ結合と呼びます。

等結合の結果には、社員表の部署IDと部署表の部署IDが両方とも残ります。2つの列の値は必ず同じなので、片方は情報として余分です。共通の列を1つにまとめた等結合を、自然結合と呼びます。

社員表と部署表を部署IDで結合したときの、結果の列の違い
結合の種類結果の列
等結合氏名・部署ID・部署ID・部署名の4列
自然結合氏名・部署ID・部署名の3列

PostgreSQLでは、JOIN ONで条件を書くと両方の表の列がすべて出ます。JOIN USINGやNATURAL JOINで書くと、共通の列は1つにまとまって出ます。一致しない行を残す外部結合は、JOINの記事で説明しています。

直積はすべての組合せ、商はすべてを満たすものを求める

直積は、2つの表の行を条件なしにすべて組み合わせます。4行の社員表と2行の部署表の直積は、4×2=8行です。SQLではCROSS JOINで書きます。

直積の8行のうち、部署IDが一致する行だけを選ぶと、等結合と同じ4行になります。等結合は、直積に選択をかけたものです。図の直積では、この4行に色を付けています。

商は、直積の逆に当たる演算です。割られる表の中から、割る表の値をすべて持つものを求めます。例えば、受講記録を必修研修の表で割ると、必修研修を全部受けた人が分かります。

SQLには、商を1語で書く指定がありません。GROUP BYで人ごとにまとめ、受けた必修研修の数が必修研修の総数と等しい人を残す形で書きます。総数を数える部分には、サブクエリを使います。

和・差・積は、列の並びが同じ表どうしで使う

和・差・積は、2つの表を行の集まりとみなして計算する集合演算です。和はどちらかの表にある行を集め、両方にある行は1行にします。差は一方の表にだけある行を残し、積は両方の表にある行だけを残します。

集合演算は、列の数と、対応する列の型がそろった表どうしでしか使えません。行と行を比べて同じかどうかを決めるので、列の並びが違うと比べられないためです。PostgreSQLの公式ドキュメントも、UNION・INTERSECT・EXCEPTの2つの問合せにこの条件を求めています。この条件を満たす2つの表は、和両立であるといいます。

SQLでは、和をUNION、差をEXCEPT、積をINTERSECTで書きます。どれも重複した行を除き、ALLを付けたときだけ重複を残します。なお、集合演算の積は両方にある行を残す演算で、すべての組合せを作る直積とは別物です。

演算を選んで、入力と結果の表を比べる

次の図で演算を選ぶと、入力の表と結果の表が切り替わります。入力の表で色が付いた行や列は、結果に使う部分です。図は実際のデータベースには接続しておらず、結果はあらかじめ計算した固定の値です。

社員
氏名部署ID
田中D1
佐藤D2
鈴木D1
高橋D2
部署IDがD1の行だけを取り出します。列はそのまま残り、行だけが減ります。
SELECT * FROM 社員 WHERE 部署ID = 'D1';
結果(2行)
氏名部署ID
田中D1
鈴木D1

参考にした資料

練習問題(全6問)

Q1表から、指定した列だけを取り出す関係演算はどれ?
Q2SQLのSELECT文で、WHERE句が受け持つ関係演算はどれ?
Q34行の表Aと3行の表Bの直積は何行になる?
Q4和・差・積の集合演算を使える2つの表の条件として、正しいものはどれ?
Q5受講記録(氏名, 研修)を、必修研修(研修)で割る商の結果はどれ?
Q6等結合と自然結合の違いとして、正しいものはどれ?

選んでから「採点する」を押すと、解説つきで答え合わせができます。

関連記事

おすすめの本 PR

セキュリティとデータベースは、基本情報技術者試験の対策本でまとめて学べます。

目的別の本の選び方を見る

データベースの記事を続けて読む

データベース 全36本中18本目