Consulta del explorador de datos para todos los usuarios activos (Lurkers + Posters)

Estoy buscando proporcionar a nuestro equipo estadísticas sobre la cantidad de usuarios activos actuales que tenemos, con la siguiente definición de ‘Usuario Activo’:

Usuarios que hayan leído mientras iniciaron sesión o que hayan publicado en nuestro foro durante el último año.

Tenemos muchos usuarios en el modo de lista de correo que responden por correo electrónico, por lo que perderemos a muchos si simplemente recopilamos el número de lectores según esta consulta:

También puedo obtener el número de quienes han publicado aquí:

Simplemente soy demasiado tonto para combinarlos con un OR para que capturemos ambos grupos. ¿Puedes ayudarme?

Esto debería devolverte todos los usuarios que hayan leído algo mientras iniciaron sesión o que hayan publicado en el último año. El explorador de datos también mostrará cuántos son.

SELECT p.user_id
FROM posts p
LEFT JOIN topics t ON t.id = p.topic_id
WHERE p.created_at::date > CURRENT_TIMESTAMP - INTERVAL '365 days'
 AND t.deleted_at IS NULL
 AND t.visible = TRUE
 AND t.closed = FALSE
 AND t.archived = FALSE
 AND t.archetype = 'regular'
 AND p.deleted_at IS NULL
UNION
SELECT u.user_id
FROM user_visits u
WHERE u.posts_read > 0
 AND u.visited_at > CURRENT_TIMESTAMP - INTERVAL '365 days'
ORDER BY user_id

Probablemente exista una forma más eficiente de hacerlo, pero funciona :slight_smile:. Si deseas un período específico, podrías cambiar > CURRENT_TIMESTAMP - INTERVAL '365 days' (ambas ocurrencias) por algo como esto: BETWEEN '20200101'::date AND '20210101'::date.

¡Proporcionaste información y referencias excelentes en tu pregunta! Solo tuve que seleccionar lo adecuado y combinarlo.

¡Gracias! Creo firmemente en facilitar que otros puedan ayudar cuando sea posible.

UNION: eso era la laguna en mi conocimiento de SQL. ¡Todo resuelto ahora, gracias! Publicaré mi consulta final aquí una vez que esté más refinada.

Al final, terminé haciendo algo un poco diferente, ya que necesitaba más información y UNION resultó ser un poco restrictivo. También quería desglosarlo por grupos. Creo que logré el éxito “hackeando” la consulta de Lurkers Activos incluida con otra que tengo para extraer información específica de grupos:

-- [params]
-- int :number_of_days = 365
-- string :group_name = trust_level_0

With included_users AS (
SELECT
gu.user_id
FROM group_users gu
JOIN groups g
ON g.id = gu.group_id
WHERE g.name = :group_name
),
posts_by_user AS (
    SELECT COUNT(*) AS posts, p.user_id
    FROM posts p
    LEFT JOIN topics t ON t.id = p.topic_id
    WHERE p.created_at::date > CURRENT_TIMESTAMP - INTERVAL ':number_of_days' day
        AND t.deleted_at IS NULL
        AND t.visible = TRUE
        AND t.closed = FALSE
        AND t.archived = FALSE
        AND t.archetype = 'regular'
        AND p.deleted_at IS NULL
    GROUP BY p.user_id
), 
posts_read_by_user AS (
    SELECT SUM(posts_read) AS posts_read, uv.user_id
    FROM user_visits uv
    WHERE uv.posts_read > 0
        AND uv.visited_at > CURRENT_TIMESTAMP - INTERVAL ':number_of_days' day
    GROUP BY uv.user_id
)

SELECT
    u.id AS "user_id",
    u.username_lower AS "username",
    u.last_seen_at,
    COALESCE(pbu.posts, 0) AS "posts_created",
    COALESCE(prbu.posts_read, 0) AS "posts_read"
FROM users u
LEFT JOIN posts_by_user pbu ON pbu.user_id = u.id
LEFT JOIN posts_read_by_user prbu ON prbu.user_id = u.id
WHERE u.active = true
    AND u.id > 0
    AND u.id IN (SELECT user_id FROM included_users)
    AND (COALESCE(pbu.posts, 0) > 0 OR COALESCE(prbu.posts_read, 0) > 0)
ORDER BY u.id

Gracias por compartir esto. Intenté usarlo y también un código muy similar en consultas de insignias, pero obtengo este error:

Violación de contrato:
La consulta no devuelve una columna 'granted_at'

¿Me falta algo en el código para poder usar esta consulta en el sistema de insignias? Mi caso de uso es automatizar el grupo de ‘lurkers’ :slight_smile:

¡Astuto!

Las consultas de insignias son bastante complejas y solo requieren que se devuelvan un ‘user_id’ y ‘granted_at’. Así que necesitarás hackear esto un poco.

Te recomiendo que investigues los temas sobre consultas de insignias (léelos atentamente) y que lo intentes. También te recomiendo que solo lo ejecutes una vez al día, ya que de lo contrario podría ser un poco pesado.

¡Cuéntanos cómo te va!