Gracias, @SaraDev, esto nos resulta útil. Dado que somos una comunidad pequeña con personal mucho más activo que los usuarios habituales, yo (bueno, ChatGPT y yo) modificamos la consulta para poder ejecutar usuarios habituales y usuarios del personal por separado o combinados. Y me gusta verlo representado gráficamente, así que lo modifiqué para habilitarlo.
Recientemente vi cómo descargar el esquema de la base de datos en este consejo de @tyler.lamparter, y lo subo a ChatGPT al principio de estas sesiones; hace que sea más fácil pedirle a chatty que separe staff, por ejemplo.
-- [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) -- Todos los usuarios
OR (:include_staff = 0 AND user_id NOT IN (SELECT user_id FROM staff_users)) -- Solo usuarios no del personal
OR (:include_staff = 2 AND user_id IN (SELECT user_id FROM staff_users)) -- Solo personal
)
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) -- Todos los usuarios
OR (:include_staff = 0 AND user_id NOT IN (SELECT user_id FROM staff_users)) -- Solo usuarios no del personal
OR (:include_staff = 2 AND user_id IN (SELECT user_id FROM staff_users)) -- Solo personal
)
GROUP BY month
)
SELECT
d.day::DATE AS date, -- ✅ Eje X para graficar
ROUND((d.dau::numeric / NULLIF(m.mau, 0)::numeric) * 100, 1)::FLOAT AS dau_mau_ratio -- ✅ Eje Y para graficar
FROM daily_users d
JOIN monthly_users m ON date_trunc('month', d.day) = m.month
ORDER BY date
-- 0 = Solo No Personal, 1 = Todos los Usuarios, 2 = Solo Personal