この記事では、Select文のグループ化と表の結合について、初心者にも分かりやすく、図解付きで丁寧に解説しています!
Select文
- 基本形:
Select 列名 From 表名 Where 条件
グループ化:Group By
- Group Byでグループ化できる。
- グループ化の基本形:
Select Sum(合計する列名) From 表名 Group By グループ化する列名Select AVG(平均する列名) From 表名 Group By グループ化する列名 - グループ化に対する絞込みはHavingを使う
Group By グループ化する列名 Having 条件
表を縦に結合:Union
- 表同士を結合:
Select 列名 From 表名1 Union All Select 列名 From 表名2 - 表同士を結合(重複する行は削除):
Select 列名 From 表名1 Union Select 列名 From 表名2
表を横に結合:Join
- 共通のデータが存在する場合のみ結合:
Select 列名 From 表名1 Inner Join 結合する表名2
On 表名1.列名 = 表名2.列名 - 共通のデータが存在しない場合も結合:
Select 列名 From 表名1 Left Outer Join 結合する表名2
On 表名1.列名 = 表名2.列名
(復習)Select文 – 基本形
Select文はデータを抽出するためのSQLです。Select文では、Fromの後に抽出したいテーブル、Selectの後に抽出したい列を指定します。条件を指定したい場合はWhereの後ろに書きます。
Select文の基本形
Select 列名 From テーブル名 Where 条件

Where句を指定しないことも出来ます。この場合は、全てのデータを抽出します。
Select 氏名,役職 From 社員表

また、列名を指定せずに「*」を使うと、全ての列を抽出できます。
Select * From 社員表 Where 所属部署=’人事部’

Select文の基本的な使い方はこちらの記事で解説しています。

データをグループ化する:Group By
Select文で抽出したデータをグループ化して、合計値を求めたり、平均値を求めるには「Group By」を使います。
抽出したデータの合計値を求める
Select Sum(合計する列名) From 表名 Group By グループ化する列名
抽出したデータの平均値を求める
Select Avg(平均する列名) From 表名 Group By グループ化する列名
例えば、顧客ごとの注文金額の合計値を抽出するSelect文はこうなります。注文金額を合計した列の列名を「注文合計」としたいので、「As ‘注文合計’」で列に名前を付けました。
Select 顧客名,Sum(注文金額) As ‘注文合計’ From 注文表 Group By 顧客名

例えば、顧客ごとの注文金額の平均値を抽出するSelect文はこうなります。
Select 顧客名,Avg(注文金額) As ‘注文平均’ From 注文表 Group By 顧客名

グループを条件で絞り込む:Having
グループ化したデータを条件で絞り込むには「Having」を使います。
グループを絞り込む
Group By グループ化する列名 Having 絞り込む条件
例えば、合計3,000円以上注文した顧客を抽出するSelect文はこうなります。
Select 顧客名,Sum(注文金額) As ‘注文合計’ From 注文表
Group By 顧客名 Having Sum(注文金額) >= 3,000

表を縦に結合する:Union
表同士を縦に結合するには「Union」を使います。
表同士を結合する
Select 列名 From 表名1 Union All Select 列名 From 表名2
表同士を結合する(重複する行は削除)
Select 列名 From 表名1 Union Select 列名 From 表名2
例えば、軽音部表と美術部表をUnion Allで結合するSelect文はこうなります。
Select * From 軽音部表 Union All Select * From 美術部表

軽音部表と美術部表をUnionで結合するSelect文はこうなります。Unionで結合するため、重複する行は削除されます。
Select * From 軽音部表 Union Select * From 美術部表

表を横に結合する:Join
表同士を横に結合するには「Join」を使います。「On 表名1.列名 = 表名2.列名」で結合の条件を指定します。
共通のデータが存在する場合のみ結合
Select 列名 From 表名1 Inner Join 結合する表名2 On 表名1.列名 = 表名2.列名
共通のデータが存在しない場合も結合
Select 列名 From 表名1 Left Outer Join 結合する表名2 On 表名1.列名 = 表名2.列名
例えば、生徒表とクラス表をInner JoinするSelect文はこうなります。
Joinを使う場合、どの表の列なのかを判別するために、「表名.列名」の表記で列を指定します。今回の例で言うと、生徒表のクラス列とクラス表のクラス列同士で表を結合するため、「On 生徒表.クラス = クラス表.クラス」と条件を指定します。
Select 生徒表.氏名, 生徒表.クラス, クラス表.担任 From 生徒表 Inner Join クラス表 On 生徒表.クラス = クラス表.クラス
Inner Joinを使っているので、クラス表に存在しない「Z組」の岡健は抽出されません。

生徒表とクラス表をOuter JoinするSelect文はこうなります。
Left Outer Joinを使っているので、クラス表に存在しない「Z組」の岡健も抽出されます。しかし、Z組はクラス表に存在しないので、担任はNullとなります。
Select 生徒表.氏名, 生徒表.クラス, クラス表.担任 From 生徒表 Left Outer Join クラス表 On 生徒表.クラス = クラス表.クラス

応用情報技術者試験での出題例
令和4年度秋期問28
応用情報技術者
午前試験 令和4年度秋期問28
“商品”表に対して、次のSQL文を実行して得られる仕入先コード数は幾つか。

ア 1 イ 2 ウ 3 エ 4
正解は”ウ”
①SELECT AVG (販売単価 – 仕入単価) FROM 商品
まずはこのSQLの結果から求めます。このSQLでは商品テーブルに格納されている全データの販売単価 – 仕入単価の平均値を取得しています。よって、
(200+200+100+900+400+200+300+500+500+300)÷10=360
で、360という値を返します。
ここから問題文のSQLは以下のようになります。
SELECT DISTINCT 仕入先コード FROM 商品 WHERE (販売単価 – 仕入単価) >360
(販売単価 – 仕入単価)が360を超えるデータを探してみましょう。下の表の黄色データが360を超えるデータになります。

「Distinct 仕入先コード」と書かれているので、重複する仕入先コードは削除します。

よって取得できる仕入先コードが3個なので答えはウです。
令和3年度秋期問29
応用情報技術者
午前試験 令和3年度秋期問29
“部門別売上別”表から、部門コードごと、期ごとの売上を得るSQL文はどれか。


正解は”イ”
UNIONでは表同士を純粋に足し算します。
①SELECT 部門コード,’第1期’ AS 期, 第1期売上 AS 売上 FROM 部門別売上
このSQLから得られる結果は以下の通りです。

②SELECT 部門コード,’第2期’ AS 期, 第2期売上 AS 売上 FROM 部門別売上
このSQLから得られる結果は以下の通りです。

以上2つの表を足し算し、部門コード、期で昇順に並び替えると問題文の表が取得できます。
ちなみに、
ア INTERSECTでは2つの表で共通している項目が取得できます。今回だと共通している部分が無いので結果は何もなしになります。
ウ CROSS JOINでは2つの表に存在するデータの全ての組み合わせを取得できます。ちなみに問題文のSQLは引っ掛けになっているのでCROSS JOIN本来の使い方とは違う形で書かれています。
エ INNER JOINでは表同士を横に結合できます。こちらも問題文のSQLは引っ掛けになっているのでINNER JOIN本来の使い方とは違う形で書かれています。