データベース
下の動画はこの節の解説ではありません。 解説動画の雰囲気を知っていただくための見本として、「AI・機械学習」の動画を再生します。
この節の解説動画はプレミアム限定です。プレミアムなら全科目・全節が見放題!
プレミアムで見るSQLは、リレーショナルデータベースを操作するための言葉です。プログラミング言語のように手順を書き並べるのではなく、「どの表の、どの行の、どの列がほしいのか」を宣言するだけで結果が返ってきます。この節では、まずSQLを2つの言語(DDLとDML)に分けて全体像をつかみ、もっともよく使われるSELECT文を、基本構文から条件指定、そして複数の表をつなぐJOIN句まで順に組み立てていきます。JOIN句の種類は令和7年度に、比較演算子と論理演算子は令和5年度に問われています。実際に書けるところまで持っていくつもりで読み進めてください。
簡単にいうと
SQLの命令は「入れ物を作る係」と「中身を出し入れする係」の2種類!DDLが入れ物、DMLが中身。この区別ができれば、命令の名前も自然に整理できるよ。
① SQLとは
SQL(Structured Query Language)は、リレーショナルデータベースにおけるデータベース言語です。
データベース言語とは、データベースやテーブルの作成、変更、削除、データの検索、登録、変更、削除など、データベースの操作を行うための言語です。
② SQLが動くしくみ
SQLの位置づけを図で追うと、次のようになります。
| 順番 | 誰が | 何をするか |
|---|---|---|
| ① | ユーザ | SQL(SELECT… FROM… など)を書く |
| ② | DBMS | SQLで記述されたプログラムを解釈する |
| ③ |
具体例
1つの表を作って使って消すまで
商品を管理する表を例に、DDLとDMLを順に使ってみます。
① 表を作る(DDL)
```
CREATE TABLE 商品表 (
商品コード CHAR(4),
商品名 VARCHAR(50),
単価 INTEGER
)
```
この時点で、枠だけがあって中身が空の表ができます。
② データを入れる(DML)
```
INSERT INTO 商品表 VALUES ('SA1', 'A', 200)
```
1行が追加されます。
③ データを読む(DML)
```
SELECT * FROM 商品表

データベース言語の種類(DDL・DML・DCL)
試験のポイント
簡単にいうと
SELECT文は3行で書ける!「何を」「どこから」「どんな条件で」。しかもこの3行が、そのまま射影・結合・選択に対応しているんだ。
① 基本の3行
基本的なSELECT文の構成は次のとおりです。
| 句 | 書くもの | 意味 |
|---|---|---|
| SELECT <列名> | 抽出する列 | 抽出する列を指定する(複数の列がある場合は「,(カンマ)」で区切る) |
| FROM <表名> |
簡単にいうと
条件の書き方は3グループ。大小を比べる比較演算子、条件をつなぐ論理演算子、そして範囲や空白やパターンを見るその他の表記。ANDとORの優先順位は、ちょっとした落とし穴だよ!
① 3つのグループ
SELECT文のWHERE句で指定できる抽出条件には、比較演算子、論理演算子などがあります。加えて、BETWEENやLIKEといったその他の表記もあります。
② 比較演算子
| 演算子 | 書式 | 意味 |
|---|---|---|
| = | A=B |
簡単にいうと
複数の表をつなぐのがJOIN!「両方にある行だけ」がINNER、「片方は全部残す」がOUTER。残したほうにない値はNULLになる——ここが試験の急所だよ。
① JOIN句とは
表を結合するにはWHERE句で表の結合条件を指定することもできますが、一般的にはJOIN句を用います。
複数の表を結合する際に用いられるJOIN句には、内部結合(INNER JOIN)と外部結合(OUTER JOIN)の2種類があります。
② 3つの結合を1枚の表で
| 結合される行 | 値がNULL(空欄)になるケース | |
|---|---|---|
| INNER JOIN |
動画・テキスト・過去問・AI添削まですべて網羅!
予備校代の1/10以下で、独学の不安をまるごと解決できます
| データベース(受注表、商品表、顧客表など)からデータを抽出する |
| ④ | DBMS | SQLの条件に合致したデータをユーザに渡す |
ユーザが直接データベースのファイルを触ることはありません。必ずDBMSを介します。第2節で学んだ「アプリケーションからデータベースを独立させる」という働きが、ここに現れています。
③ 2種類のデータベース言語
データベース言語には、データ定義言語とデータ操作言語があります。
データ定義言語(DDL:Data Definition Language)
データベースの構造や容量、整合性、管理方法などの定義を行う言語を指します。
| 名称 | 内容 |
|---|---|
| CREATE | 新しいデータベース、テーブル、索引などを作成する |
| ALTER | 既に存在するデータベース、テーブル、索引などに対し、内容を変更する |
| DROP | 既に存在するデータベース、テーブル、索引などを削除する |
データ操作言語(DML:Data Manipulation Language)
テーブル内のデータ検索、テーブルへのデータ登録、変更、削除などのデータ操作を行う言語を指します。
| 名称 | 内容 |
|---|---|
| SELECT | 条件を指定し、テーブル内のデータを検索する |
| INSERT | テーブルに対し、新規の行を追加する |
| UPDATE | 特定の行や列を指定し、データの内容を変更する |
| DELETE | 特定の行を指定し、データを削除する |
④ 2つの違いを一言で
| DDL | DML | |
|---|---|---|
| 対象 | 入れ物(表そのもの) | 中身(表の中のデータ) |
| 英語 | Definition=定義 | Manipulation=操作 |
| 命令 | CREATE、ALTER、DROP | SELECT、INSERT、UPDATE、DELETE |
⑤ 似た命令の取り違えに注意
DDLとDMLには、意味が近いのに対象が違う命令が対になって存在します。
| やりたいこと | 表そのもの(DDL) | 表の中のデータ(DML) |
|---|---|---|
| 作る | CREATE TABLE | INSERT |
| 変える | ALTER TABLE | UPDATE |
| 消す | DROP TABLE | DELETE |
DROPとDELETEの違いが、とくに問われやすい点です。
⑥ DMLの4つは対応関係で覚える
DMLの4命令は、データ操作の基本4動作(CRUD)に対応しています。
| 動作 | 英語 | SQL |
|---|---|---|
| 作成 | Create | INSERT |
| 読み取り | Read | SELECT |
| 更新 | Update | UPDATE |
| 削除 | Delete | DELETE |
CRUD(クラッド)という言葉は第9章のシステム開発でも登場します。どんな業務システムも、突き詰めればこの4つの操作の組み合わせでできている、という見方ができるようになります。
```
| 商品コード | 商品名 | 単価 |
|---|---|---|
| SA1 | A | 200 |
④ データを変える(DML)
```
UPDATE 商品表 SET 単価 = 250 WHERE 商品コード = 'SA1'
```
単価が250になります。
⑤ 列を追加する(DDL)
```
ALTER TABLE 商品表 ADD 原産国 VARCHAR(20)
```
表の構造そのものが変わります。既存の行には、原産国の値がない(NULL)状態で列が増えます。
⑥ データを消す(DML)
```
DELETE FROM 商品表 WHERE 商品コード = 'SA1'
```
行が消えますが、表の枠組みは残ります。
⑦ 表を消す(DDL)
```
DROP TABLE 商品表
```
表そのものが消えます。もう `SELECT * FROM 商品表` は実行できません。
この違いが実務で意味を持つ場面
システムの運用中に「データを全部消したい」という要望が出たとき、DROPとDELETEのどちらを使うかで結果がまったく違います。
| 使う命令 | 結果 | 復旧 |
|---|---|---|
| DELETE | 行が消え、表は残る | ロールバックで戻せることが多い |
| DROP | 表ごと消える | 表の再作成から必要。取り返しがつきにくい |
第3節で学んだトランザクションとの関係でいえば、DDLはトランザクションの管理外に置かれることが多く、DROPしてしまうとロールバックで戻せない、という点も押さえておきましょう。
確認してみましょう
> 次の記述の正誤を判定せよ。
> a CREATE、ALTER、DROPはデータ定義言語(DDL)に分類される。
> b SELECT、INSERT、UPDATE、DELETEはデータ操作言語(DML)に分類される。
> c DELETEは、既に存在するテーブルそのものを削除する命令である。
解答 a:○ b:○ c:×
| 対象の表 |
| 問い合せ対象の表を指定する(複数の表がある場合は「,(カンマ)」で区切る) |
| WHERE <条件式> | 条件 | 行に対する検索条件を指定する |
② 関係演算との対応
第2節で学んだ関係演算と、SELECT文の各句はきれいに対応しています。
| 句 | 何を指定するのか | 対応する関係演算 |
|---|---|---|
| SELECT | どの列を指定するのか | 射影 |
| WHERE | どの行を指定するのか | 選択 |
この対応を押さえておけば、「射影と選択のどちらが列でどちらが行か」で迷うことはなくなります。SELECTの後ろに列名を書くという、実際に手を動かして覚えた事実から逆算できるからです。
③ 使用例——社員表と部署表
以下の2つの表を使って、SELECT文の書き方を確かめていきます。
社員表
| 社員コード | 社員名 | 所属コード | 年齢 |
|---|---|---|---|
| 1001 | 太田 | 11 | 20 |
| 1002 | 田中 | 14 | 32 |
| 1003 | 鈴木 | 14 | 28 |
| 2001 | 佐藤 | 12 | 48 |
| 3002 | 小林 | 13 | 39 |
部署表
| 所属コード | 所属名 |
|---|---|
| 11 | 人事部 |
| 12 | 営業部 |
| 13 | 総務部 |
| 14 | 経理部 |
④ 列を選ぶ(射影)
例1:社員表から、社員名を抽出する場合
```
SELECT 社員名 FROM 社員表
```
| 社員名 |
|---|
| 太田 |
| 田中 |
| 鈴木 |
| 佐藤 |
| 小林 |
例2:社員表から、社員名と所属コードを抽出する場合
```
SELECT 社員名,所属コード FROM 社員表
```
複数の列はカンマで区切ります。
例3:社員表から、すべての行・列を抽出する場合
```
SELECT * FROM 社員表
```
「社員表」と同様の結果になります。アスタリスク(*)は「すべての列」を意味します。
⑤ 行を絞る(選択)
例4:社員表から、所属コードが14のデータをすべて抽出する場合
```
SELECT * FROM 社員表
WHERE 所属コード=14
```
| 社員コード | 社員名 | 所属コード | 年齢 |
|---|---|---|---|
| 1002 | 田中 | 14 | 32 |
| 1003 | 鈴木 | 14 | 28 |
例5:社員表から、年齢が30以上の社員名と年齢を抽出する場合
```
SELECT 社員名,年齢 FROM 社員表
WHERE 年齢>=30
```
| 社員名 | 年齢 |
|---|---|
| 田中 | 32 |
| 佐藤 | 48 |
| 小林 | 39 |
射影(SELECTで列を絞る)と選択(WHEREで行を絞る)を同時に行っていることに注目してください。
⑥ 列名の書き方
複数の表を扱うときは、どの表の列かを明示します。
> 列名の指定は原則「表名.列名」とするが、列名だけで判断がつく場合は、「列名」だけでも構いません。
社員表と部署表の両方に「所属コード」という列があるので、この列を指すときは `社員表.所属コード` のように書き分ける必要があります。一方「社員名」は社員表にしかないので、そのまま書いても構いません。
具体例
書きたい結果からSELECT文を組み立てる
「経理部に所属する社員の名前だけを知りたい」という要望を、段階を追ってSQLにしてみましょう。
手順1:どの表を使うか(FROM)
社員名は社員表にあります。所属コードも社員表にあります。したがって社員表だけで足ります。
```
FROM 社員表
```
手順2:どの列がほしいか(SELECT)
社員名だけです。
```
SELECT 社員名
```
手順3:どの行に絞るか(WHERE)
経理部は所属コード14です。
```
WHERE 所属コード=14
```
組み立てた結果
```
SELECT 社員名 FROM 社員表
WHERE 所属コード=14
```
| 社員名 |
|---|
| 田中 |
| 鈴木 |
この順番で考えるのがコツ
SQLは `SELECT → FROM → WHERE` の順に書きますが、考える順番は `FROM → WHERE → SELECT` のほうが自然です。
1. どの表に、ほしい情報があるか
2. そのうちどの行が対象か
3. その行のどの列を見せるか
実際、DBMSの内部でもこの順番で処理されます。表を読み、行を絞り、最後に列を取り出す——という流れです。
アスタリスクを使うときの注意
`SELECT *` はすべての列を返すので便利ですが、実務では避けられることがあります。
| 問題 | 理由 |
|---|---|
| 不要な列まで転送される | 通信量とメモリを無駄に使う |
| 表に列が追加されると結果が変わる | プログラムが想定外の列を受け取る |
| 必要な情報が読み手に伝わらない | SQLを見ても何がほしいのか分からない |
試験で `SELECT *` が出てきたら「すべての列」と理解すれば十分ですが、実務では必要な列を明示するのが定石、ということも知っておくとよいでしょう。
確認してみましょう
> 次の記述の正誤を判定せよ。
> a SELECT句は抽出する列を指定し、複数の列はカンマで区切る。
> b WHERE句は行に対する検索条件を指定する。
> c SELECT句は関係演算の選択に、WHERE句は射影に対応する。
解答 a:○ b:○ c:×

射影(列の抽出)
試験のポイント
| > | A>B | AがBより大きいデータを抽出 |
| < | A<B | AがBより小さいデータを抽出 |
| >= | A>=B | AがBより大きいか、等しいデータを抽出 |
| <= | A<=B | AがBより小さいか、等しいデータを抽出 |
| <> | A<>B | AとBが異なるデータを抽出 |
「等しくない」が「≠」ではなく「<>」である点に注意してください。「より小さいか、より大きい」=「等しくない」という発想から来ています。
③ 論理演算子
| 演算子 | 書式 | 意味 |
|---|---|---|
| AND | 条件1 AND 条件2 | 条件1と条件2の両方を満たすデータを抽出 |
| OR | 条件1 OR 条件2 | 条件1か条件2のどちらかを満たすデータを抽出 |
| NOT | NOT 条件 | 条件を満たさないデータを抽出 |
④ 論理演算子の優先順位
ここが狙われるところです。
> 論理演算子には優先順位があり、1つのステートメントで複数の論理演算子を使用すると、最初にNOT、次にAND、最後にORが評価されます。つまり、ORよりもANDが優先されるということです。また、カッコがある場合はカッコの中が優先されます。
| 順位 | 演算子 |
|---|---|
| 1 | NOT |
| 2 | AND |
| 3 | OR |
算数で「かけ算が足し算より先」なのと同じ構造です。AND が掛け算、OR が足し算にあたる、と対応づけると覚えやすくなります。
⑤ その他の条件
| 表記 | 意味 |
|---|---|
| 列名 BETWEEN A AND B | 指定した列の値が、A以上B以下のデータを抽出 |
| 列名 IS NULL | 指定した列の値が、空白のデータを抽出 |
| 列名 IS NOT NULL | 指定した列の値が、空白でないデータを抽出 |
| 列名 LIKE 'パターン' | 指定した列の値が、パターンに一致したデータを抽出 |
LIKEで使うワイルドカード
| 記号 | 意味 |
|---|---|
| % | 0文字以上の任意の文字列 |
| _(アンダースコア) | _と同じ位置にある任意の1文字 |
⑥ BETWEENの書き換え
BETWEEN述語は、列値の範囲を検索条件として指定する述語です。表Rの列Aが10以上、30以下の行を求めるときは、次のように指定します。
```
SELECT * FROM R
WHERE A BETWEEN 10 AND 30
```
これは、次のように指定したのと同じ意味になります。
```
SELECT * FROM R
WHERE A>=10 AND A<=30
```
BETWEENは「以上・以下」であって「より大きい・より小さい」ではない——つまり両端を含みます。この点は計算を伴う問題で効いてきます。
⑦ NULLの扱い
NULLは「値がない」ことを表す特別な状態です。空文字列("")やゼロとは違います。
NULLの判定には `= NULL` ではなく `IS NULL` を使います。NULLは「値が不明」なので、「不明なものと等しいか」を比べることができないからです。`列名 = NULL` と書いても、何も抽出されません。
具体例
設例で確かめる——社員表への問い合わせ
社員表
| 社員コード | 社員名 | 所属コード | 年齢 |
|---|---|---|---|
| 1001 | 太田 | 11 | 20 |
| 1002 | 田中 | 14 | 32 |
| 1003 | 鈴木 | 14 | 28 |
| 2001 | 佐藤 | 12 | 48 |
| 3002 | 小林 | 13 | 39 |
例6:年齢が30以上でかつ所属コードが14のデータをすべて抽出する
```
SELECT * FROM 社員表
WHERE 年齢>=30 AND 所属コード=14
```
| 社員コード | 社員名 | 所属コード | 年齢 |
|---|---|---|---|
| 1002 | 田中 | 14 | 32 |
年齢30以上は田中・佐藤・小林、所属コード14は田中・鈴木。両方を満たすのは田中だけです。
例7:年齢が20以上30以下のデータを抽出する
```
SELECT * FROM 社員表
WHERE 年齢 BETWEEN 20 AND 30
```
| 社員コード | 社員名 | 所属コード | 年齢 |
|---|---|---|---|
| 1001 | 太田 | 11 | 20 |
| 1003 | 鈴木 | 14 | 28 |
太田の20が含まれていることに注目してください。BETWEENは両端を含みます。
例8:社員名の1文字目が「田」で始まるデータを抽出する
```
SELECT * FROM 社員表
WHERE 社員名 LIKE '田%'
```
| 社員コード | 社員名 | 所属コード | 年齢 |
|---|---|---|---|
| 1002 | 田中 | 14 | 32 |
「太田」は抽出されません。「田」で始まるという条件だからです。もし「田を含む」を表したいなら `LIKE '%田%'` と書きます。
LIKEのパターンを使い分ける
| 書き方 | 意味 | この表での結果 |
|---|---|---|
| `LIKE '田%'` | 田で始まる | 田中 |
| `LIKE '%田'` | 田で終わる | 太田 |
| `LIKE '%田%'` | 田を含む | 太田、田中 |
| `LIKE '_田'` | 2文字目が田の2文字 | 太田 |
ANDとORの優先順位で結果が変わる例
```
WHERE 所属コード=11 OR 所属コード=14 AND 年齢>=30
```
ANDが先に評価されるので、これは次と同じ意味です。
```
WHERE 所属コード=11 OR (所属コード=14 AND 年齢>=30)
```
結果は太田(所属11)と田中(所属14かつ30以上)の2件です。
もし「所属が11か14で、かつ30歳以上」を表したいなら、カッコで明示しなければなりません。
```
WHERE (所属コード=11 OR 所属コード=14) AND 年齢>=30
```
こちらの結果は田中だけ(太田は20歳なので外れる)になります。
意図した条件を確実に表すには、迷わずカッコを付ける——これは実務でも試験でも通用する方針です。

選択(行の抽出)
試験のポイント
| 2つのテーブルに共通する行のみ |
| どちらかにない行は結合されない |
| LEFT OUTER JOIN | FROM句で指定したテーブルの全行 | LEFT OUTER JOIN句で指定したテーブルで、結合条件に合致しないレコードの値はNULLになる |
| RIGHT OUTER JOIN | RIGHT OUTER JOIN句で指定したテーブルの全行 | FROM句で指定したテーブルで、結合条件に合致しないレコードの値はNULLになる |
③ INNER JOIN(内部結合)
INNER JOIN句は、2つのテーブル(表)を結合するとき、結合条件(ON句)を満たすレコードだけを結合します。両方の表に共通の値を持たない(結合条件を満たさない)レコードは除外されます。
また、単に「JOIN」と記述した場合も「INNER JOIN」句の扱いになります。
構文
```
FROM テーブルA
INNER JOIN テーブルB
ON 結合条件
```
④ 例で確かめる
顧客表
| 顧客ID | 名前 |
|---|---|
| C001 | 山田 太郎 |
| C002 | 佐藤 花子 |
| C003 | 鈴木 一郎 |
注文表
| 注文ID | 顧客ID | 商品名 |
|---|---|---|
| O1001 | C001 | ノートPC |
| O1002 | C003 | タブレット |
| O1003 | C004 | スマホ |
INNER JOINの場合
```
SELECT 顧客表.顧客ID, 顧客表.名前, 注文表.商品名
FROM 顧客表
INNER JOIN 注文表
ON 顧客表.顧客ID = 注文表.顧客ID;
```
| 顧客ID | 名前 | 商品名 |
|---|---|---|
| C001 | 山田 太郎 | ノートPC |
| C003 | 鈴木 一郎 | タブレット |
ポイント……顧客ID「C002(注文表の顧客IDにない)」と顧客ID「C004(顧客表の顧客IDにない)」のレコードは結合されません。INNER JOINは2つのテーブルの結合条件に合致するレコードのみを結合するため、両方のテーブルにおいて結合条件に合致しないレコードは結合されません。
⑤ OUTER JOIN(外部結合)
OUTER JOIN句は、2つのテーブル(表)を結合するとき、片方のテーブルはそのままで、もう片方のテーブルについて、結合条件に合致したレコードを結合します。
OUTER JOIN句には、さらに「LEFT OUTER JOIN句」「RIGHT OUTER JOIN句」「FULL OUTER JOIN句」の3種類がありますが、FULL OUTER JOIN句はMySQLでは非対応であり、1次本試験で出題されたこともないため、ここでは扱いません。
⑥ LEFT OUTER JOIN(左外部結合)
```
FROM テーブルA
LEFT OUTER JOIN テーブルB
ON 結合条件
```
同じ2つの表で実行すると、
| 顧客ID | 名前 | 商品名 |
|---|---|---|
| C001 | 山田 太郎 | ノートPC |
| C002 | 佐藤 花子 | NULL |
| C003 | 鈴木 一郎 | タブレット |
ポイント……FROM句で指定した表(顧客表)を基準に結合します。FROM句で指定した表は全行が維持され、LEFT OUTER JOIN句で指定した表(注文表)で、結合条件に合致するレコードが結合されます。結合条件に合致しないレコード(顧客ID「C002」)は、結合されたテーブルではNULL(空欄)になります。
⑦ RIGHT OUTER JOIN(右外部結合)
```
FROM テーブルA
RIGHT OUTER JOIN テーブルB
ON 結合条件
```
| 顧客ID | 名前 | 商品名 |
|---|---|---|
| C001 | 山田 太郎 | ノートPC |
| C003 | 鈴木 一郎 | タブレット |
| C004 | NULL | スマホ |
ポイント……RIGHT OUTER JOIN句で指定した表(注文表)を基準に結合します。RIGHT OUTER JOIN句で指定した表は全行が維持され、FROM句で指定した表(顧客表)で、結合条件に合致するレコードが結合されます。結合条件に合致しないレコード(顧客ID「C004」)は、結合されたテーブルではNULL(空欄)になります。
⑧ 見分け方
| 書き方 | 基準になる表 | 全行が残る表 |
|---|---|---|
| FROM A INNER JOIN B | — | どちらも残らない(共通部分のみ) |
| FROM A LEFT OUTER JOIN B | A(FROM句の表) | A |
| FROM A RIGHT OUTER JOIN B | B(JOIN句の表) | B |
LEFTは左側(FROM句に書いた表)、RIGHTは右側(JOIN句に書いた表)。構文を横書きで並べたときの位置関係がそのまま名前になっています。
⑨ どれを使うべきかの判断
| 知りたいこと | 使う結合 |
|---|---|
| 注文のある顧客だけ知りたい | INNER JOIN |
| 注文がない顧客も含めて全顧客を知りたい | LEFT OUTER JOIN(顧客表をFROM句に) |
| 顧客登録のない注文も含めて全注文を知りたい | RIGHT OUTER JOIN(注文表をJOIN句に) |
「〜していない人も含めて」という要望が出たら外部結合——この対応を覚えておくと、実務でも試験でも判断がつきます。
具体例
設例 登録ユーザごとの商品登録状況
> あるメーカーでは、カスタマーサポートや新製品のプロモーションなどのために、Webサイトを通じて顧客にユーザ登録と購入した商品の登録を働きかけている。「登録ユーザ」表はユーザ登録済みの顧客に関するデータを、「商品登録管理」表はユーザ登録済みの顧客が自身で登録した購入済み商品に関するデータを表している。なお、ユーザ登録をしている顧客の中には、商品登録を行っていない者もいる。(令和7年度第12問 改題)
得たい結果(購入商品登録状況)の一部は次のとおりです。
| 顧客ID | アカウント名 | 商品コード | 登録台数 |
|---|---|---|---|
| C0001 | keizai.ichiro | P101 | 1 |
| C0002 | seisaku.jiro | (空欄) | 0 |
| C0003 | zaimu.saburo | P103 | 1 |
| C0004 | kaikei.haruka | P102 | 3 |
| C0004 | kaikei.haruka | P101 | 1 |
| C0005 | keiei.natsumi | (空欄) | 0 |
SQL文の空欄①と②に入る語句の組み合わせとして、最も適切なものを選びます。
```
SELECT
登録ユーザ.顧客ID,
登録ユーザ.アカウント名,
商品登録管理.商品コード,
COUNT(商品登録管理.商品コード) AS 登録台数
FROM
登録ユーザ ① 商品登録管理
ON 登録ユーザ.顧客ID = 商品登録管理.顧客ID
GROUP BY ②
ORDER BY 登録ユーザ.顧客ID ASC, 登録台数 DESC;
```
> ア ①INNER JOIN/②登録ユーザ.顧客ID, 登録ユーザ.アカウント名, 商品登録管理.商品コード
> イ ①INNER JOIN/②登録ユーザ.顧客ID, 登録台数
> ウ ①RIGHT OUTER JOIN/②登録ユーザ.顧客ID
> エ ①LEFT OUTER JOIN/②登録ユーザ.顧客ID, 登録ユーザ.アカウント名, 商品登録管理.商品コード
> オ ①LEFT OUTER JOIN/②登録ユーザ.顧客ID, 登録台数
解答 エ
①の判断
得たい結果には、商品登録を行っていないC0002とC0005も含まれています(商品コードが空欄、登録台数0)。

結合(表の結合)
試験のポイント
プレミアムプラン
¥9,800〜/ 買い切り・自動更新なし(税込)
決済はStripe(世界最高水準・PCI-DSS準拠)で安全に処理されます。カード情報は当サービスに保存されません。
②の判断
GROUP BY句には、SELECT句に指定されているすべての非集約列(集合関数以外の列)を含める必要があります(次節で学びます)。
SELECT句には、顧客ID、アカウント名、商品コードの3つの非集約列があります。したがって②にはこの3つすべてが必要です。
この問題から学べること
「〜していない者もいる」という一文が、外部結合を選ぶ決定的な手がかりになっています。問題文の中に必ずこうした手がかりが置かれているので、得たい結果の表に「空欄」や「0」があるかを確認することが、結合の種類を見極める近道です。