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.04.03
【Laravel】パスワードリセット メールアドレス入力欄のバリデーションに独自ルールを追加する
2023.07.19
【RPA】PowerAutomateDesktop(PAD)を使ったブラウザ操作自動化
2025.02.27
Google Apps Script(GAS)からPostgreSQLに接続する方法を徹底解説!Cloud Run Functionsの活用法も紹介
2025.09.10
ページ表示速度・LCP改善に向けてSlickスライダーの最適化をやってみた