Digamos que hay 100 soluciones en un mes. Hay veinte personas que pertenecen a algún grupo y los usuarios comenzaron a marcar sus respuestas como soluciones, un total de veinte de ellas. Quiero una consulta donde pueda especificar su ID de grupo principal en el script y obtener los datos por mes para mostrar que, para este mes, es 20/100, es decir, un 20%.
He intentado hacer las consultas más detalladas para facilitar su comprensión y mantenimiento en el futuro.
WITH users_groups AS (
SELECT
user_id,
g.id,
g.name AS group_name
FROM users u
INNER JOIN user_actions ua ON ua.user_id = u.id
LEFT JOIN groups g ON g.id = u.primary_group_id
WHERE ua.action_type = 15
GROUP BY user_id, g.id
),
tt_solution_by_month AS (
SELECT
date_part('year', created_at) AS year,
date_part('month', created_at) AS month,
COUNT(*) AS "total"
FROM user_actions ua
WHERE ua.action_type = 15
GROUP BY date_part('year', created_at), date_part('month', created_at)
ORDER BY date_part('year', created_at) ASC, date_part('month', created_at)
),
tt_solution_groups_by_month AS (
SELECT
date_part('year', created_at) AS year,
date_part('month', created_at) AS month,
ug.group_name,
COUNT(*) AS "tt_groups"
FROM user_actions ua
INNER JOIN users_groups ug ON ug.user_id = ua.user_id
WHERE ua.action_type = 15
GROUP BY ug.group_name, date_part('year', created_at), date_part('month', created_at)
ORDER BY date_part('year', created_at) ASC, date_part('month', created_at), ug.group_name)
SELECT
ts.year,
ts.month,
COALESCE(tsg.group_name,'sin grupo'),
tt_groups,
total,
TRUNC((tt_groups::decimal/total::decimal) *100,1) AS "%"
FROM tt_solution_groups_by_month tsg
INNER JOIN tt_solution_by_month ts
ON ts.year = tsg.year AND ts.month = tsg.month
Avísame si este es el resultado que esperabas o si debo ajustar algo.
¡Casi perfecto! No necesito las columnas tt_groups ni total, solo el número del porcentaje. En cuanto a la columna group_name, será una consulta para un solo grupo, así que tampoco hace falta esa columna. Dentro del código de la consulta, simplemente especificaré el primary_group_id, de modo que buscará solo las soluciones de este grupo exacto.
-- [params]
-- string :primary_group_id
WITH users_groups AS (
SELECT
user_id,
g.id,
g.name group_name
FROM users u
INNER JOIN user_actions ua ON ua.user_id = u.id
LEFT JOIN groups g ON g.id = u.primary_group_id
WHERE ua.action_type = 15
AND u.primary_group_id = :primary_group_id
GROUP BY user_id, g.id
),
tt_solution_by_month AS (
SELECT
date_part('year', created_at) AS year,
date_part('month', created_at) AS month,
COUNT(*) AS "total"
FROM user_actions ua
WHERE ua.action_type = 15
GROUP BY date_part('year', created_at), date_part('month', created_at)
ORDER BY date_part('year', created_at) ASC, date_part('month', created_at)
),
tt_solution_groups_by_month AS (
SELECT
date_part('year', created_at) AS year,
date_part('month', created_at) AS month,
ug.group_name,
COUNT(*) AS "tt_groups"
FROM user_actions ua
INNER JOIN users_groups ug ON ug.user_id = ua.user_id
WHERE ua.action_type = 15
GROUP BY ug.group_name, date_part('year', created_at), date_part('month', created_at)
ORDER BY date_part('year', created_at) ASC, date_part('month', created_at), ug.group_name)
SELECT
ts.year,
ts.month,
TRUNC((tt_groups::decimal/total::decimal) *100,1) AS "%"
FROM tt_solution_groups_by_month tsg
INNER JOIN tt_solution_by_month ts
ON ts.year = tsg.year AND ts.month = tsg.month