2026
May
07
FILTER句でCASE文を使わずに条件集計する方法
今回はPostgreSQLのFILTER句について紹介します。
ステータス毎の件数を取得する時にCASE文を書いて集計することは多いかと思います。
ただ、CASE文では冗長になりがちです。
そこでFILTER句を使うことでスッキリと書くことができるようになります。
※この記事はPostgreSQL 16.13 で動作確認してます。
FILTER句とは
FILTER 句は集計関数(COUNT、SUM、AVG など)に対して
「この条件を満たす行だけを集計対象にする」 という絞り込みを付け加えられる構文です。
構文
集計関数(...) FILTER (WHERE 条件式)CASE文
SELECT
COUNT(CASE WHEN status = '完了' THEN 1 END) AS 完了件数,
COUNT(CASE WHEN status = '処理中' THEN 1 END) AS 処理中件数,
COUNT(CASE WHEN status = 'キャンセル' THEN 1 END) AS キャンセル件数
FROM orders;FILTER句
SELECT
COUNT(*) FILTER (WHERE status = '完了') AS 完了件数,
COUNT(*) FILTER (WHERE status = '処理中') AS 処理中件数,
COUNT(*) FILTER (WHERE status = 'キャンセル') AS キャンセル件数
FROM orders;CASE文よりFILTER句の方が読みやすく直感的に理解しやすくなっています。
GROUP BYを使った集計
SELECT
department,
SUM(amount) AS 売上合計,
SUM(amount) FILTER (WHERE order_date >= DATE_TRUNC('month', CURRENT_DATE)) AS 当月件数,
SUM(amount) FILTER (WHERE order_date >= DATE_TRUNC('month', CURRENT_DATE) - INTERVAL '1 month'
AND order_date < DATE_TRUNC('month', CURRENT_DATE)) AS 先月件数
FROM sales
GROUP BY department;1レコードで当月分、先月分を取得できるようになりました。
GROUP BYだけでは複数行になりますが、FILTER を使えば 1行にまとめて比較しやすくなります。
まとめ
・FILTER (WHERE 条件) を集計関数の後ろに付けるだけで条件付き集計ができる
・CASE WHEN と結果は同じだが、書き方がシンプルで意図が伝わりやすい。
・集計関数と組み合わせ可能
・GROUP BY とも併用できる
CASE文ばっかりのSQLを書いているなと感じたら、FILTER句も試してみてください。
読み返したときに「何を集計しているか」がすぐわかるSQLは、保守時にも役立ちます。
このカテゴリの最新記事
2024.08.29
ChatGPT APIとC#(またはPython)を活用したAIメール応答システムの構築方法
2024.02.14
【Laravel】MiddlewareでBasic認証をかける
2026.03.17
Claude Codeとは?基本コマンドと使い方を解説
2023.09.27
Laravel Mix(webpack)からViteに移行してみる