-- [params]
-- date :start_date = 2023-01-01
-- date :end_date = 2024-01-01
WITH date_series AS (
SELECT generate_series(:start_date::date, :end_date::date, '1 day'::interval) AS date
),
DAU AS (
SELECT date(date) AS day, COUNT(DISTINCT user_id) AS dau_count
FROM user_visits
JOIN date_series ON date(user_visits.visited_at) = date_series.date
GROUP BY date
),
MAU AS (
SELECT date_series.date, COUNT(DISTINCT user_visits.user_id) AS mau_count
FROM user_visits
JOIN date_series ON date(user_visits.visited_at) >= date_series.date - INTERVAL '30 days'
AND date(user_visits.visited_at) <= date_series.date
GROUP BY date_series.date
)
SELECT
DAU.day,
(DAU.dau_count::FLOAT / NULLIF(MAU.mau_count, 0)) * 100 AS "DAU/MAU",
DAU.dau_count,
MAU.mau_count
FROM DAU
JOIN MAU ON DAU.day = MAU.date
ORDER BY DAU.day
DAU: DAU CTEは、各日(dau_count)にサイトを訪問したユニークユーザー数を計算します。これは、user_visitsテーブルとdate_series CTEを、訪問日がシリーズの日付と一致するという条件で結合することによって行われます。結果は日付ごとにグループ化され、各日のユニークユーザー数を取得します。
MAU: MAU CTEは、date_series内の各日付に先行する30日間にサイトを訪問したユニークユーザー数を計算します。これは、user_visitsテーブルとdate_series CTEを結合し、訪問日がシリーズの日付から30日前から、その日付まで(その日付を含む)の間にあることによって行われます。結果は日付ごとにグループ化され、各30日間の期間のユニークユーザー数を取得します。
-- [params]
-- date :start_date = 2024-01-01
-- date :end_date = 2025-01-01
WITH date_series AS (
SELECT generate_series(:start_date::date, :end_date::date, '1 month'::interval) AS month_start
),
MAU AS (
SELECT
date_trunc('month', date_series.month_start) AS month,
COUNT(DISTINCT user_visits.user_id) AS mau_count
FROM user_visits
JOIN date_series
ON date(user_visits.visited_at) >= date_series.month_start - INTERVAL '1 month'
AND date(user_visits.visited_at) < date_series.month_start + INTERVAL '1 month'
GROUP BY date_trunc('month', date_series.month_start)
)
SELECT
month::date AS "月",
mau_count AS "月間アクティブユーザー数"
FROM MAU
WHERE month <= CURRENT_DATE
ORDER BY month
-- [params]
-- int :months_ago = 3
-- int :include_staff = 1
WITH staff_users AS (
SELECT user_id FROM group_users WHERE group_id = 3
),
daily_users AS (
SELECT
date_trunc('day', visited_at)::DATE AS day,
COUNT(DISTINCT user_id) AS dau
FROM user_visits
WHERE visited_at >= CURRENT_DATE - INTERVAL ':months_ago months'
AND (
(:include_staff = 1) -- すべてのユーザー
OR (:include_staff = 0 AND user_id NOT IN (SELECT user_id FROM staff_users)) -- スタッフ以外のみ
OR (:include_staff = 2 AND user_id IN (SELECT user_id FROM staff_users)) -- スタッフのみ
)
GROUP BY day
),
monthly_users AS (
SELECT
date_trunc('month', visited_at)::DATE AS month,
COUNT(DISTINCT user_id) AS mau
FROM user_visits
WHERE visited_at >= CURRENT_DATE - INTERVAL ':months_ago months'
AND (
(:include_staff = 1) -- すべてのユーザー
OR (:include_staff = 0 AND user_id NOT IN (SELECT user_id FROM staff_users)) -- スタッフ以外のみ
OR (:include_staff = 2 AND user_id IN (SELECT user_id FROM staff_users)) -- スタッフのみ
)
GROUP BY month
)
SELECT
d.day::DATE AS date, -- ✅ グラフのX軸
ROUND((d.dau::numeric / NULLIF(m.mau, 0)::numeric) * 100, 1)::FLOAT AS dau_mau_ratio -- ✅ グラフのY軸
FROM daily_users d
JOIN monthly_users m ON date_trunc('month', d.day) = m.month
ORDER BY date
-- 0 = スタッフ以外のみ, 1 = すべてのユーザー, 2 = スタッフのみ