こんにちは、さるまりんです。
データ集計、プログラムが最も得意とする分野のひとつですね。
今回はPostgreSQLで前月のデータを集計してみます。
前月の範囲を取得
DATE_TRUNC
とINTERVAL
を使って前月の開始日と終了日を求めます。
-- 前月の開始日
SELECT DATE_TRUNC('month', CURRENT_DATE) - INTERVAL '1 month';
-- 前月の終了日
SELECT DATE_TRUNC('month', CURRENT_DATE) - INTERVAL '1 day';
DATE_TRUNC('month', CURRENT_DATE)
は現在の月の最初の日(1日)を取得します。
その一月前が前月の1日、前日が前月の末日となります。
WHEREでフィルタリング
取得したいデータの範囲をBETWEEN
を使って指定します。
SELECT
SUM(total_amount) AS total_sales,
COUNT(*) AS total_orders
FROM
orders
WHERE
order_date BETWEEN
DATE_TRUNC('month', CURRENT_DATE) - INTERVAL '1 month' AND
DATE_TRUNC('month', CURRENT_DATE) - INTERVAL '1 day';
注文データの入っているorders
テーブルより、total_amount
の合計をSUM(total_amount)
でtotal_sales
として、注文数をCOUNT(*)
でtotal_orders
として集計しています。
この時order_date
はTIMESTAMP
やDATE
型のカラムである必要があります。
クエリ全体の例
users
テーブルをcreated_at
で集計し、前月の新規ユーザー数を取得します。
SELECT
DATE_TRUNC('month', created_at) AS month,
COUNT(*) AS new_users
FROM
users
WHERE
created_at BETWEEN
DATE_TRUNC('month', CURRENT_DATE) - INTERVAL '1 month' AND
DATE_TRUNC('month', CURRENT_DATE) - INTERVAL '1 day'
GROUP BY
month
ORDER BY
month;
月ごとの集計例
前月だけでなくて複数の月分のデータを集計するにはGROUP BY
で月単位にします。
SELECT
TO_CHAR(DATE_TRUNC('month', order_date), 'YYYY-MM') AS month,
SUM(total_amount) AS total_sales
FROM
orders
WHERE
order_date >= DATE_TRUNC('month', CURRENT_DATE) - INTERVAL '6 months'
GROUP BY
DATE_TRUNC('month', order_date)
ORDER BY
month;
DATE_TRUNC
に'month'
を指定して月単位にしましたが、'day'
を指定すると日単位、'hour'
で時間単位の集計もできます。
用途によってどの精度にするかは検討しながら使ってみます。
データベースはデータの専門家です。任せられることは専門に任せて、いいプログラムを書きたいです。
読んでくださってありがとうございました。
それではまた!