WHERE句で絞り込まず、SELECT句で各条件に該当するレコード数を集計する。
この時、書き方がいくつかあるので紹介。
※GROUP BYで集計できない(不足がある)ケースを想定してね!
サンプル
以下のデータ(witnesses)を想定して記述していきます。
名前 | 號数 |
---|---|
夜行A | 0 |
きゃどくら | 2 |
チャンミダ | 28 |
課長 | 29 |
銅寺 | 10 |
このデータにおいて以下のそれぞれの集計していきます。
- 號数が10以上
- 號数が10未満
1. CASEの利用
昔からある書き方です。
各レコードに対してCASEで条件判定し、該当する場合は1、そうでなければ0とします。
その結果をSUMすることで該当数を出しています。
後述の別手法も同様ですが、WHERE句による絞り込みと比較し、
対象となるレコード全体は減らさずに集約関数の対象となるレコードを絞り込むことができるので、
一文で様々な条件で集計などをかける場合に使用します。
SELECT
SUM(CASE 號数 >= 10 THEN 1 ELSE 0 END) AS 二桁立会人
, SUM(CASE 號数 < 10 THEN 1 ELSE 0 END) AS 一桁立会人
FROM
witnesses
下記のSELECT文の結果にある各フラグをSUMしていると捉えるとわかりやすいと思います。
SELECT
名前
, 號数
, CASE 號数 >= 10 THEN 1 ELSE 0 END AS 二桁立会人フラグ -- 0 or 1
, CASE 號数 < 10 THEN 1 ELSE 0 END AS 一桁立会人フラグ -- 0 or 1
FROM
witnesses
2. FILTER句の利用
SQL:2003で追加された機能です。
SELECT
count(名前) FILTER(WHERE 號数 >= 10) AS 二桁立会人
, count(名前) FILTER(WHERE 號数 < 0) AS 一桁立会人
FROM
witnesses
COUNTなどの集約関数の末尾にWHERE句同様の記述することで対象の絞り込み可能です。
CASEの利用と比較して直感的に、かつ慣れ親しんだ記述が可能です。
僕はこっちが好きです。
その他
下記リンクのような書き方もあります。
https://qiita.com/zb185423/items/f20b21ca041989410b5f
万が一疑問が残った方は、下記SELECT文で確かめてみるとわかりやすいかも。
SELECT
名前
, 號数
, 號数 >= 10 AS 二桁立会人フラグ -- TRUE or FALSE
, 號数 < 10 AS 一桁立会人フラグ -- TRUE or FALSE
FROM
witnesses
元記事にもある通り、両フラグともTRUE/FALSEとなるはずです。
非NULLはCOUNTの対象なのでそのままだと全レコードが対象となってしまいます。
その対応のために「条件判定 OR NULL」とするわけですね。
勉強になります。
詳しくは元記事の方が丁寧に書いてくれてますのでそちらをご参照ください!
まとめ
同じ結果を求めるために様々な書き方があることがわかりますね。
もちろん、どんな時でも今回の書き方を使えばいいわけではないですね。
WHERE句で対象レコードを絞りこめたほうがパフォーマンス的にはよいので、
まずはWHERE句でレコードそのものを絞り込めないか、から検討したほうがいいと思います。