【SQL】集約関数(または集合関数)
集約:複数行を1行にまとめること
| 関数 | 説明 | 備考 |
|---|---|---|
COUNT(*) |
テーブルのレコード(行)を数える | NULLも含めて数える |
COUNT(列名) |
その列に値が入っている行の数を数える | NULLは除く |
SUM |
テーブルの数値列のデータを合計する | 数値型のみOK |
AVG |
テーブルの数値列のデータの平均を求める | 〃 |
MAX |
テーブルの任意の列のデータの最大値を求める | 順序を付けられるなら、どんなデータ型でもOK |
MIN |
テーブルの任意の列のデータの最小値を求める | 〃 |
- NULLが含まれていても計算結果は「NULL」にならない
ただし、全行が「NULL」の場合、結果は「NULL」を返す ※COUNTは0を返す - NULLはあらかじめ計算式から除外される
日付の最大値、最小値
/* 日付も求められる */
SELECT MAX(torokubi), MIN(torokubi)
FROM Shohin;
max | min
------------+------------
2009-11-11 | 2008-04-28
【要注意】AVGで割る数は?
/* 前提 */
SELECT shiire_tanka
FROM Shohin;
shiire_tanka
--------------
500
320
2800
2800
5000
-- NULL
790
-- NULL
(8 rows)
shiire_tankaは、NULLも含めて8行ある。
NULLは計算式から除外されてしまう↓
SELECT COUNT(shiire_tanka)
FROM Shohin;
/* NULL以外の行の数 */
count
-------
6
【検証】shiire_tankaについて計算する
SELECT AVG(shiire_tanka)
FROM Shohin;
avg
-----------------------
2035.0000000000000000
SELECT SUM(shiire_tanka)
FROM Shohin;
sum
-------
12210
合計金額を何で割ったら「2035.0000000000000000」になる?
/* PostgreSQLでは「整数÷整数=整数」と、
余りは切り捨てられてしまうため小数点まで追加 */
SELECT 12210.0 / 6 AS "6で割る";
6で割る
-----------------------
2035.0000000000000000
SELECT 12210.0 / 8 AS "8で割る";
8で割る
-----------------------
1526.2500000000000000
全行の数「8」で割りたいのに、NULLの2行は最初からなかったことになっている
→ COALESCE関数で解決できそう
重複値を除外して集約関数を使う
DISTINCTキーワードをCOUNT関数の引数にする
/* shohin_bunruiの入っている行すべて */
SELECT COUNT(shohin_bunrui)
FROM Shohin;
count
-------
8
/* 重複している値を除外する */
SELECT COUNT(DISTINCT shohin_bunrui)
FROM Shohin;
count
-------
3
この書き方はNG
/* 前提 */
SELECT shohin_bunrui
FROM Shohin;
shohin_bunrui
---------------
衣服
事務用品
衣服
キッチン用品
キッチン用品
キッチン用品
キッチン用品
事務用品
/* NG */
SELECT DISTINCT COUNT(shohin_bunrui)
FROM Shohin;
/* DISTINCTを書いた意味がない
(重複している行も数えている) */
count
-------
8
COUNTが走る →「8」の1行だけとれる- 1行しかないので、
DISTINCTするものがない
関連記事:【SQL】DISTINCTとGROUP BY:重複を除外
参考書籍:ミック『SQL 第2版 ゼロからはじめるデータベース操作』(翔泳社)