タイガーラック クリエイティブブログ
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は、保守時にも役立ちます。

このカテゴリの最新記事

関連記事

SHOP LIST

タイガーラック株式会社

〒577-0056
大阪府東大阪市長堂1-3-14 TOKUYASU Bld.