GROUP BY句を使った集計で、年ごと、月ごとのデータを集計するケースは多いと思う。

今回はPostgreSQLで、四半期ごとのデータを集計する方法を紹介する。

事前に売上日を年・月に分解しておく

まずは事前作業として、date_part関数を使ってDATE型として登録されている売上日を年・月に分解する。

SELECT
  date_part('year', 売上日) as year
  , date_part('month', 売上日) as month
  , SUM(売上) as 売上
FROM
  tbl_uriage
GROUP BY
  year, month
;

これでまず年月ごとの集計ができたはずだ。

CASE式を使って四半期ごとに集計する方法

次に上記のSQLをサブクエリとして使う。

四半期に分ける処理はCASE式を使うと良い。

SELECT
  tmp.year,
  CASE
    WHEN tmp.month BETWEEN 1 and 3 THEN '1Q'
    WHEN tmp.month BETWEEN 4 and 6 THEN '2Q'
    WHEN tmp.month BETWEEN 7 and 9 THEN '3Q'
    WHEN tmp.month BETWEEN 10 and 12 THEN '4Q'
  END as quater
  , SUM(tmp.売上) as 売上
FROM (
  SELECT
    date_part('year', 売上日) as year
    , date_part('month', 売上日 as month
    , SUM(売上) as 売上
  FROM
    tbl_uriage
  GROUP BY
    year, month
) tmp
GROUP BY year, quater
ORDER BY year DESC, quater DESC
;

上記のSQLを実行すると四半期ごとの売上データを集計することができる。

CEIL関数を使ってもっとシンプルに!

CASE式を使うと処理の内容はわかりやすいものの、コード量が多くなる。

実は小数を切り上げる関数「CEIL関数」を使うことで以下のとおりシンプルに書くことができるのだ。

SELECT
  tmp.year
  , CEIL(tmp.month / 3)||'Q' as quater
  , SUM(tmp.売上) as 売上
FROM (
  SELECT
    date_part('year', 売上日) as year
    , date_part('month', 売上日 as month
    , SUM(売上) as 売上
  FROM
    tbl_uriage
  GROUP BY
    year, month
) tmp
GROUP BY year, quater
ORDER BY year DESC, quater DESC
;

蓋を開けてみれば非常に簡単な話なのだが、ここに至るまでにかなりの時間を要した。
特にCEIL関数を使った四半期集計の方法は、目からウロコだったので実務でも積極的に活用していきたい。