Digamos que haja 100 soluções em um mês. Existem vinte pessoas que pertencem a algum grupo e as pessoas começaram a marcar suas respostas como soluções, totalizando vinte delas. Quero uma consulta em que eu especifique o ID do grupo principal delas no script e obtenha os dados por mês para mostrar, neste mês, 20/100 - 20%.
Olá Konrad, desculpe pelo atraso.
Ainda estou validando algumas consultas, mas vou aproveitar para confirmar: este é o resultado que você está aguardando?
Tentei tornar as consultas mais detalhadas para facilitar a compreensão e a manutenção no 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,'sem 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
Avise-me se este é o resultado esperado ou se devo ajustar algo.
Quase perfeito! Não preciso das colunas tt_groups e total, apenas do número da porcentagem. Quanto à coluna group_name, como será uma consulta para um único grupo, também não há necessidade de incluí-la. No código da consulta, vou especificar apenas o primary_group_id, para que ele busque soluções apenas desse grupo específico.
-- [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