資格道場 › レッスン一覧 › データベース
データベース・5/13・12分

関係代数と結合・集合演算

ゴール

表から列を取る「射影」、行を取る「選択」、表をつなぐ「結合」、集合演算(和・差・積・直積)を見分けられるようにする。SQL の内部結合の結果が何行・どの値になるかを、表を指でたどって答えられるようにする。

演算名を当てる問題と、2つの表を結合した SQL の結果を当てる問題は、科目Aのデータベース分野でくり返し出ている。実務でも「どの表をどのキーでつなぐと何行になるか」は、API 設計や集計ミスの原因調べにそのまま使える。

このレッスンで稽古する(用語チェック・過去問)

結論:関係代数は「表を加工する操作の名前」

関係代数は、表(関係)から新しい表を作る操作に名前を付けたもの。試験で一番よく問われるのは 射影=列を取る、選択=行を取る、結合=表どうしをつなぐ の3つ。

Excel でたとえると、射影は「要らない列を隠す」、選択は「フィルタで行を絞る」、結合は「VLOOKUP で別の表の列を持ってくる」に近い。

用語の対応:関係=表、属性=列、タプル=行。

最重要:射影・選択・結合の区別

演算 何を取り出す/作る 表の形の変化 SQL での対応
射影(projection) 指定した**列(属性)**だけ 列が減る・行数は基本そのまま SELECT 列名
選択(selection) 条件に合う**行(タプル)**だけ 行が減る・列はそのまま WHERE 条件
結合(join) 共通の列の値が等しい行どうしをつなぐ 2つの表が横に合体 FROM A, B WHERE A.x = B.x

見分け方は 「縦に切ったら射影、横に切ったら選択」。表Xから商品番号と数量の列だけ残った表Yを作る操作は、列を取っているので射影になる(平成31年度春期 問28)。

自然結合は、同じ名前の列で結合し、その列を1本にまとめる結合。結合したあとに選択と射影を組み合わせる問題もよく出る。

射影:列を取る選択:行を取る縦に切る→列が減る横に切る→行が減るSELECT 列名WHERE 条件
射影は表を縦に切って列を残し、選択は横に切って行を残す。

集合演算:和・差・積・直積

表を「行の集合」とみなして行う演算。和・差・積は、2つの表の列の数と型がそろっていること(和両立)が前提になる。

演算 記号 意味 SQL
和 ∪ どちらかにある行(重複は1つにまとめる) UNION
差 − Rにあって、Sに無い行 EXCEPT
積(共通集合) ∩ 両方にある行 INTERSECT
直積 × Rの全行とSの全行の総当たり(m行×n行) SELECT * FROM R, S(条件なし)
商 ÷ 割り算のような演算(細部は出題が少ない) —

直積は「全組み合わせ」なので、3行×4行なら12行になる。直積に WHERE で「キーが等しい」という条件を付けると結合になる、と覚えるとつながる。

直積 R×S:全組み合わせR\S12341231-11-21-31-42-12-22-32-43-13-23-33-43行×4行=12行緑=キーが等しい組WHEREで緑だけ残すと結合
直積はRの3行とSの4行の総当たりで12行になり、キーが等しい組だけ残すと結合になる。

等価変形 R−(R−S) = R∩S

R−S は「Rだけにある行」。それをRから引くと、残るのは「Sにもある行」なので R∩S になる。

例:R={1,2,3}、S={2,3,4} → R−S={1} → R−{1}={2,3}=R∩S。迷ったら小さい数の集合を置いて試すのが一番速い。

R元の表123S比べる表234R−SRだけにある行1R−(R−S)Rから{1}を引く23残り{2,3}=R∩S(両方にある行)
R={1,2,3}からR−S={1}を引くと{2,3}が残り、R∩Sと同じになる。

UNION がエラーになる条件

UNION でつなぐ2つの SELECT は、列の数がそろっていて、対応する列の型に互換性が無いとエラーになる。

重複行があってもエラーにはならない(UNION が1行にまとめるだけ)。NULL があっても、ソートされていなくてもエラーにはならない。

SQL の内部結合:結果の当て方

FROM 表A, 表B WHERE 表A.列 = 表B.列 は内部結合。両方の表に相手が見つかった行だけが結果に残る。

結合の種類 相手が見つからない行
内部結合(この形) 消える(NULL 行は出ない)
外部結合(LEFT JOIN など) 残して、相手の列を NULL で埋める

解き方の型は3ステップ。①先に、条件で絞れる側の表(例:住所=新宿の学部)を絞る。②もう一方の表を1行ずつ見て、相手が見つかる行に印を付ける。③同じ値が2回あれば2行のまま数える(勝手に合計したり、まとめたりしない)。

①新宿で絞る②相手を探す学部住所D1新宿D2渋谷D3新宿名前学部佐藤D1鈴木D2高橋D3田中D1伊藤D4赤の行は相手が無く結果から消える③結果は3行(D1の2人は別の行)名前学部住所佐藤D1新宿高橋D3新宿田中D1新宿
新宿の学部に絞ってから学生を1行ずつたどり、相手が見つかった行だけが内部結合の結果に残る。

試験での問われ方

  • 演算名を当てる問題:選択肢に結合・射影・選択・和が並ぶ。列が減ったら射影、行が減ったら選択。
  • 組み合わせの問題:結合したあとに「行も列も減っている」なら選択と射影。
  • SQL と集合演算の対応:UNION=和、EXCEPT=差、INTERSECT=積、条件なしの FROM R, S=直積。
  • 内部結合の結果を当てる問題:同じ名前の列(住所など)がどちらの表のものかでひっかける。相手の無い行に NULL を出した選択肢や、同じ行を1つにまとめた選択肢は誤り。
例題 1

結合のあとの演算を当てる(出典:平成30年度 秋期 基本情報技術者試験 午前 問28)

関係 X と Y を自然結合した後,関係 Z を得る関係代数演算はどれか。
X:
学生番号氏名学部コード
1山田太郎A
2情報一郎B
3鈴木花子A
4技術五郎B
5小林次郎A
6試験桃子A
Y:
学部コード学部名
A工学部
B情報学部
C文学部
Z:
学部名学生番号氏名
情報学部2情報一郎
情報学部4技術五郎

ア 射影と和
イ 選択
ウ 選択と射影
エ 選択と和

出典:平成30年度 秋期 基本情報技術者試験 午前 問28

解き方と答えを見る
  1. X と Y を学部コードで自然結合すると、6人の学生それぞれに学部名が付いた表になる(6行)。
  2. Z は情報学部の2人(学生番号2・4)だけなので、行が6→2に減っている → 学部コード=B(情報学部)の行を取る「選択」。
  3. Z の列は学部名・学生番号・氏名の3つで、学部コードの列が無い → 列を取る「射影」。
  4. 行も列も減っているので「選択と射影」。和は行を足す演算なので関係ない。

答え:ウ(選択と射影)

例題 2

住所がどちらの表のものかを見落とさない(出典:平成31年度 春期 基本情報技術者試験 午前 問29)

“学生”表と“学部”表に対して次の SQL 文を実行した結果として,正しいものはどれか。
学生:
氏名所属住所
応用花子理新宿
高度次郎人文渋谷
午前桜子経済新宿
情報太郎工渋谷
学部:
学部名住所
工新宿
経済渋谷
人文渋谷
理新宿
〔SQL 文〕 SELECT 氏名 FROM 学生, 学部 WHERE 所属 = 学部名 AND 学部.住所 = '新宿' 選択肢は結果表(列: 氏名): ア: 応用花子 イ: 応用花子 / 午前桜子 ウ: 応用花子 / 情報太郎 エ: 応用花子 / 情報太郎 / 午前桜子

ア [図] 氏名: 応用花子
イ [図] 氏名: 応用花子,午前桜子
ウ [図] 氏名: 応用花子,情報太郎
エ [図] 氏名: 応用花子,情報太郎,午前桜子

出典:平成31年度 春期 基本情報技術者試験 午前 問29

解き方と答えを見る
  1. 条件は「所属=学部名」かつ「学部.住所='新宿'」。見るのは学部表の住所で、学生表の住所ではない。
  2. 学部表で住所が新宿の学部を絞る → 工・理 の2つ。
  3. 学生表で所属が工か理の学生を探す → 応用花子(理)・情報太郎(工)。
  4. 高度次郎(人文・渋谷)と午前桜子(経済・渋谷の学部)は外れる。午前桜子は学生の住所が新宿だが、条件に関係しない。

答え:ウ(応用花子・情報太郎)

例題 3

内部結合で何行残るか(出典:平成24年度 春期 基本情報技術者試験 午前 問30)

“注文”表と“製品”表に対して,次の SQL 文を実行したときに得られる結果はどれか。 SELECT 製品名, 数量 FROM 注文, 製品 WHERE 注文.製品コード = 製品.製品コード
注文表:
日付製品コード数量
2011-04-10P2120
2011-04-15P1100
2011-04-22P450
2011-04-30P880
2011-05-06P1100
2011-05-08P370
製品表:
製品コード製品名
P1PC
P2テレビ
P3掃除機
P4冷蔵庫
P5エアコン
P6電話機
P7時計

ア | 製品名 | 数量 | |---|---| | テレビ | 120 | | PC | 100 | | 冷蔵庫 | 50 | | 掃除機 | 70 |
イ | 製品名 | 数量 | |---|---| | テレビ | 120 | | PC | 200 | | 冷蔵庫 | 50 | | 掃除機 | 70 |
ウ | 製品名 | 数量 | |---|---| | テレビ | 120 | | PC | 100 | | 冷蔵庫 | 50 | | PC | 100 | | 掃除機 | 70 |
エ | 製品名 | 数量 | |---|---| | テレビ | 120 | | PC | 100 | | 冷蔵庫 | 50 | | NULL | 80 | | PC | 100 | | 掃除機 | 70 |

出典:平成24年度 春期 基本情報技術者試験 午前 問30

解き方と答えを見る
  1. 注文表の6行を上から1行ずつ見て、製品表から同じ製品コードを探す。
  2. P2→テレビ120、P1→PC100、P4→冷蔵庫50、P8→製品表に無いので消える、P1→PC100、P3→掃除機70。
  3. 内部結合なので P8 の行は NULL にならず、消える(エの誤り)。
  4. PC の2行は別の注文なので、2行のまま残る。合計して200にはしない(イの誤り)し、1行にまとめもしない(アの誤り)。
  5. 結果は 6−1=5行。

答え:ウ(テレビ120・PC100・冷蔵庫50・PC100・掃除機70 の5行)

例題 4

内部結合の件数を数える(出典:平成28年度 秋期 基本情報技術者試験 午前 問29)

“社員”表と“部門”表に対して,次の SQL 文を実行したときの結果はどれか。
SELECT COUNT(*) FROM 社員, 部門 WHERE 社員.所属 = 部門.部門名 AND 部門.フロア = 2 社員表:
社員番号所属
11001総務
11002経理
11003営業
11004営業
11005情報システム
11006営業
11007企画
12001営業
12002情報システム
部門表:
部門名フロア
企画1
総務1
情報システム2
営業3
経理2
法務2
購買2

ア 1
イ 2
ウ 3
エ 4

出典:平成28年度 秋期 基本情報技術者試験 午前 問29

解き方と答えを見る
  1. 部門表でフロア=2の部門を絞る → 情報システム・経理・法務・購買 の4部門。
  2. 社員表で、所属がこの4部門の人を数える → 経理1人(11002)+情報システム2人(11005・12002)。法務と購買には社員がいない。
  3. COUNT(*) は結合結果の行数なので 1+2=3。部門数の4を答えないよう注意。

答え:ウ(3)

要点(試験直前に読む)

  • 縦に切る(列を取る)=射影、横に切る(行を取る)=選択、表をつなぐ=結合。
  • 結合したあとに行も列も減っていたら「選択と射影」。
  • UNION=和、EXCEPT=差、INTERSECT=積、条件なしの FROM R, S=直積(m×n行)。
  • R−(R−S)=R∩S。迷ったら {1,2,3} と {2,3,4} を置いて試す。
  • UNION がエラーになるのは列数(型)が合わないときだけ。重複・NULL・ソートは関係ない。
  • 内部結合では相手の無い行は消える。同じ値の行は別の行として数える。

ひっかけ

  • SQL の SELECT 句は「射影」。選択は WHERE 句にあたるので、名前で選ばない。
  • 住所のように同じ名前の列が両方の表にあるときは、「学部.住所」のようにどちらの表かを必ず確かめる。
  • 内部結合の結果に NULL 行がある選択肢は、外部結合と取り違えたもの。
  • 同じ商品が2回注文されていたら、結果も2行。合計や1行にまとめた選択肢は誤り。
  • 件数を数える問題では、条件に合う部門の数(4)ではなく、結合して残った行の数(3)を答える。

用語(15)

関係 かんけい(relation)
関係データベースでの「表」のこと。
属性 ぞくせい(attribute)
表の「列」のこと。
⚠ タプル(行)と取り違えない。縦が属性、横がタプル。
タプル たぷる(tuple)
表の「行」のこと(1件のデータ)。
⚠ 属性(列)とは向きが違う。
射影 しゃえい(projection)
表から指定した列だけを取り出す演算。
⚠ 選択は行を取る演算。列が減ったら射影。
選択 せんたく(selection)
表から条件に合う行だけを取り出す演算。
⚠ 射影は列を取る演算。SQL の SELECT 句は射影、WHERE 句が選択にあたるので名前にだまされない。
結合 けつごう(join)
共通の列の値が等しい行どうしをつないで、1つの表にする演算。
⚠ 直積は条件なしの総当たり。結合は直積に「キーが等しい」という条件を付けたもの。
自然結合 しぜんけつごう(natural join)
同じ名前の列で結合し、その列を1本にまとめる結合。
直積 ちょくせき(Cartesian product)
2つの表の全行どうしを総当たりで組み合わせる演算(m行×n行になる)。
⚠ SQL では条件なしの SELECT * FROM R, S。UNION(和)とは別物。
和 わ(union)
2つの表の少なくとも一方にある行を集める演算で、SQL では UNION。
⚠ 直積(総当たり)と混同しない。和は縦に積み重ねるイメージ。
差 さ(difference)
一方の表にあって、もう一方には無い行を取る演算で、SQL では EXCEPT。
⚠ R−S と S−R は結果が違う(向きがある)。
積(共通集合) せき(intersection)
両方の表にある行だけを取る演算で、SQL では INTERSECT。R−(R−S) と同じ結果になる。
⚠ 直積(×)とは別物。積∩は「両方にある行」、直積は「総当たり」。
商 しょう(division)
関係代数の割り算にあたる演算(記号÷)。
⚠ R−(R−S) の答えにはならない。
和両立 わりょうりつ(union compatible)
2つの表の列の数と、対応する列の型がそろっていること。和・差・積の前提になる。
⚠ UNION でエラーになるのは、和両立でないとき(列数が違うなど)だけ。
内部結合 ないぶけつごう(inner join)
両方の表に相手が見つかった行だけを残す結合。
⚠ 外部結合は相手の無い行も残し、NULL で埋める。
外部結合 がいぶけつごう(outer join)
相手の見つからない行も残し、相手側の列を NULL にする結合。
⚠ FROM A, B WHERE … の形は内部結合なので、NULL 行は出ない。

このレッスンの過去問

このレッスンで稽古する