この記事ではSelect文のグループ化と表の結合についてIT初心者にも分かりやすく解説します。
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文の基本形
データを検索して読取るために使用されるのがSelect文です。
Select文では、「どの表から」「どの列を」「どんな条件で」で抽出するのかを指示します。これがSelect文の基本形です。
Select 列名 From 表名 Where 条件
例えば、社員表から人事部の人を検索して、氏名と役職を抽出するSelect文はこうなります。
Select 氏名,役職 From 社員表 Where 所属部署=’人事部’
ちなみに、条件を指定せずにSelect文を実行することもできます。
その場合は全てのデータを抽出します。
Select 氏名,役職 From 社員表
こちらの記事で、他にもSelect文の使い方について解説しています。
【応用情報】SQLを解説 – 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(注文金額) 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本来の使い方とは違う形で書かれています。