基本情報技術者試験とは
基本情報技術者試験は、情報処理推進機構(IPA)が実施し、「情報処理の促進に関する法律」に基づき経済産業省が認定する国家試験である。
ITエンジニアとしてキャリアをスタートする方のIT基礎力を問う試験で、「ITエンジニアの登竜門」とも呼ばれる。
「基本情報技術者試験」の試験範囲は、IPAのWebサイトに掲載されているシラバスに明記されている。
それでは、基本情報技術者試験(科目A)のサンプル問題にチャレンジしてみよう。
問24 関係モデルにおいて表X から表Y を得る関係演算はどれか。

ア 結合(join) イ 射影(projection)
ウ 選択(selection) エ 併合(merge)
出典:基本情報技術者試験 科目A サンプル問題(2022年12月)
正解:イ
データベースとは
一定の規則に従って関連性のあるデータを蓄積したもの。
関係モデル
データの関係を集合論などの数学モデルで表現したもの。
関係データベース
行と列から構成される2次元の表で表現されるデータベースである。
データ操作
関係演算
関係演算は、関係データベースの表から目的のデータを取り出す演算である。以下のデータ操作ができる。
射影(projection) 表の中から特定の列を抽出する
選択(selection) 表の中から条件に合致した行を抽出する
結合(join) 二つ以上の表を結合して、一つの表を生成する
設問では列が抽出されているので、「射影」である。
ちなみに、「併合」という演算はない。
(以下追記:2026.9.23)
試験制度については、2027年度からの変更が予定されている。最新の試験情報はIPA公式サイトで確認しよう。
ここから実践編
さて、この3つの演算を、これからSQLiteとPythonで実際に試していこう。
なお、この記事で使用するコードは、学習用リポジトリ pc-labo-fe-exam-python の 05_kankei_model フォルダにまとめている。
(注意)以下の「SQLiteでテーブルを作る」から「結合をSQLで試す」までのコードは、1つのファイルに続けて書いていく前提の抜粋である。「SQLiteでテーブルを作る」で作った conn と cur を、そのあとのブロックでもそのまま使い続けるため、途中のブロックだけを単独でコピペして実行すると NameError になる。上から順につなげて実行するか、05_kankei_model/kankei_model.py(1本にまとまった完成版)をそのまま使ってほしい。
SQLiteでテーブルを作る
設問の表X(商品番号・商品名・価格・数量の4列)を、そのままSQLiteのテーブルとして作る。
import sqlite3
conn = sqlite3.connect(":memory:") # ファイルを作らず、メモリ上にDBを作る
cur = conn.cursor()
cur.execute("""
CREATE TABLE 商品 (
商品番号 TEXT PRIMARY KEY,
商品名 TEXT NOT NULL,
価格 INTEGER NOT NULL,
数量 INTEGER NOT NULL
)
""")sqlite3.connect(":memory:") とすると、ファイルを作らずにメモリ上だけでデータベースを試せる。学習用に何度も作り直す場合に便利である。
SQLiteはテーブル名・列名に日本語(商品、商品番号など)をそのまま使えるので、設問の表と同じ名前で作成している。
PythonからSQLiteに接続する
Pythonには sqlite3 モジュールが標準で組み込まれているため、追加のインストールなしでSQLiteを操作できる。sqlite3.connect() で接続を作り、cursor() でSQL文を実行するためのカーソルを取得する、という流れは、上のコードにすでに含まれている。
データを登録する
設問の表Xにある5行のデータを、executemany() でまとめて登録する。
cur.executemany(
"INSERT INTO 商品 (商品番号, 商品名, 価格, 数量) VALUES (?, ?, ?, ?)",
[
("A01", "カメラ", 13000, 20),
("A02", "テレビ", 58000, 15),
("B01", "冷蔵庫", 65000, 8),
("B05", "洗濯機", 48000, 10),
("B06", "乾燥機", 35000, 5),
],
)
conn.commit()SQL文の中の ? は、あとに続くタプルの値をあてはめるプレースホルダーである。値を直接文字列に埋め込まず ? を使うことで、SQLインジェクションを防げる。
射影をSQLで試す
射影は「表の中から特定の列を抽出する」演算である。商品 テーブルから、商品番号と数量の列だけを取り出してみよう。
cur.execute("SELECT 商品番号, 数量 FROM 商品")
for row in cur.fetchall():
print(row)実行結果
('A01', 20)
('A02', 15)
('B01', 8)
('B05', 10)
('B06', 5)
この結果を見比べると、設問の表Yとまったく同じ内容になっていることが分かる。SELECT 商品番号, 数量 FROM 商品 のように取り出す列を指定することで、表Xから表Yを得られる。
このようにSQLの SELECT で必要な列だけを指定すると、関係代数の射影に対応する操作を確認できる。
選択をSQLで試す
選択は「表の中から条件に合致した行を抽出する」演算である。価格が50,000円以上の商品だけを取り出してみよう。
cur.execute("SELECT * FROM 商品 WHERE 価格 >= 50000")
for row in cur.fetchall():
print(row)実行結果
('A02', 'テレビ', 58000, 15)
('B01', '冷蔵庫', 65000, 8)
WHERE 価格 >= 50000 という条件によって、5商品のうち、条件に合う2商品の行だけが取り出されている。列はすべて残っている点が、射影との違いである。
結合をSQLで試す
結合は「二つ以上の表を結合して、一つの表を生成する」演算である。設問には登場しないが、理解を深めるために、商品番号ごとの仕入先を管理する 仕入先 テーブルを追加で用意し、商品 テーブルと結合してみよう。
cur.execute("""
CREATE TABLE 仕入先 (
商品番号 TEXT PRIMARY KEY,
仕入先名 TEXT NOT NULL
)
""")
cur.executemany(
"INSERT INTO 仕入先 (商品番号, 仕入先名) VALUES (?, ?)",
[
("A01", "サンプル商会"),
("A02", "サンプル商会"),
("B01", "家電卸センター"),
("B05", "家電卸センター"),
("B06", "家電卸センター"),
],
)
cur.execute("""
SELECT 商品.商品名, 仕入先.仕入先名
FROM 商品
JOIN 仕入先 ON 商品.商品番号 = 仕入先.商品番号
""")
for row in cur.fetchall():
print(row)実行結果
('カメラ', 'サンプル商会')
('テレビ', 'サンプル商会')
('冷蔵庫', '家電卸センター')
('洗濯機', '家電卸センター')
('乾燥機', '家電卸センター')
商品 テーブルだけを見ても仕入先は分からないが、仕入先 テーブルと JOIN することで、2つの表にまたがる情報を1つの表として取り出せている。これが結合である。
基本情報の問題をもう一度解いてみる
ここまでで、射影・選択・結合をそれぞれSQLとPythonの実行結果として確認できた。3つの演算をあらためて比較すると、次のようになる。
| 演算 | 何をするか | 今回のSQL |
|---|---|---|
| 射影(projection) | 列を絞り込む | SELECT 商品番号, 数量 FROM 商品 |
| 選択(selection) | 行を絞り込む | SELECT * FROM 商品 WHERE 価格 >= 50000 |
| 結合(join) | 複数の表をつなげる | SELECT ... FROM 商品 JOIN 仕入先 ON ... |
「射影をSQLで試す」で実行した SELECT 商品番号, 数量 FROM 商品 の結果は、設問の表Yと完全に一致した。表Xから、商品番号と数量の列だけを絞り込んだものが表Y——これはまさに射影の定義そのものである。行数(5行)は変わらず、列だけが4列から2列に減っている点も、射影の特徴と一致している。したがって、正解はイ(射影)であることを、実際のSQL実行結果として確認できた。
まとめ
- 関係演算には代表的なものとして「射影(列を絞る)」「選択(行を絞る)」「結合(表をつなげる)」の3種類があるが、「併合」という演算は存在しない
- SQLiteとPythonの
sqlite3モジュールを使えば、追加のインストールなしでこれらの演算を手元で試せる - 実際にSQLを実行して結果を見比べることで、「列が絞られていれば射影」というような判断基準を、暗記ではなく体験として身につけられる
Python+SQLiteのコードを筆者のGitHubリポジトリで公開
この記事で扱ったコードは、以下の筆者のGitHubリポジトリで公開している。





コメント