【PostgreSQL】GROUP BY(グループ化)【DB入門】

2020年11月13日PostgreSQL構文

スポンサーリンク

GROUP BYとは

GROUP BYとはグループ化を行うときに使う構文です。

グループ化とは、例えば学校を例すると、

・クラスごとに合計点を計算する

・学年ごとに平均点を計算する

・教科ごとに最高点、最低点を計算する

等々、○○ごとに集計をするために使います。

 

集約関数の種類

求めたいものによって次の関数(集約関数といいます)を使います。

 

GROUP BYの注意

GROUP BYの構文としてはこのような形になります。

--GROUP BYの構文
SELECT 列名1 , SUM(列名2) , AVG(列名3) 
FROM テーブル名 
GROUP BY 列名1; --列名1でグループ化する

注意

GROUP BYで注意しないといけない点は、『SELECTからFROMまでの間に書く列は、

GROUP BYの後に書いてある列名だけそのままで書くことができる』という点です。

上の構文では、『GROUP BY 列名1』となっているため、

『SELECT 列名1 FROM テーブル名』と書くことができます。

 

逆にいうと、列名2と列名3はGROUP BYの後ろに書かれていないため、

集約関数とともに書かないといけません

そのため列名2 , 3は『SUM(列名2) , AVG(列名3)』となっています。

 

GROUP BYの注意(並び替え)

GROUP BYで集計をかけつつ並び替えも可能です。

(例えば、クラス別の合計点を計算し、合計点の高い順に並べるなど)

--ORDER BY(並び順)のSQL例
SELECT 列名1 , SUM(列名2) , AVG(列名3) 
FROM テーブル名 
GROUP BY 列名1 
ORDER BY 列名1 , SUM(列名2);

ORDER BYの後も基本的には『SELECT~FROM』の決まりと変わりありません。

つまり列名2と列名3はGROUP BYの後ろに書かれていないため、

ORDER BYでも集約関数とともに書かないといけません

以上が注意点になります。

 

SUM…合計を求める

SUMは合計値を求める関数です。

--合計を求める構文(列名2でグループ化、列名1を合計する)
select SUM(列名1) 
from テーブル名 
GROUP BY 列名2;

--例1:生徒でグループ化、合計点を取得する
select student_code , sum(score) 
from t_student_score 
group by school_code,student_code 
order by sum(score) desc;

--例2:教科でグループ化、合計点を取得する
select subject_code , sum(score) 
from t_student_score 
group by school_code,subject_code 
order by sum(score) desc;

 

Min…最小値を求める、Max 最大値を求める

Minは最小値を求める関数です。

--Minを使ったSQLの書き方
select Min(列名1) from テーブル名 GROUP BY 列名2; --最小値を求める
select Max(列名1) from テーブル名 GROUP BY 列名2; --最大値を求める

--生徒ごとに最低点、最高点を取得する
select student_code , min(score) , max(score) 
From t_student_score 
group by school_code,student_code 
order by student_code;

 

avg…平均点を求める

avgは最小値を求める関数です。

--avgを使ったSQLの書き方
select avg(列名1) from テーブル名 GROUP BY 列名2;

--生徒ごとに平均点を取得する
select student_code , avg(score) 
From t_student_score 
group by school_code,student_code 
order by student_code;

 

COUNT…行数(データの数)をカウントする

COUNTは最小値を求める関数です。

--countを使ったSQL文の例
select count(*) from テーブル名 GROUP BY 列名2;

--生徒ごとの点数データ数をカウントする
select student_code,count(*)
From t_student_score 
group by school_code,student_code 
order by student_code;