Solución

Base de datos

Vista general

Las dos claves para resolver esta pregunta son:

  1. filtrar en un rango específico de fechas
  2. contar solo usuarios únicos dado que puede haber usuarios con más de una actividad por día, y los resultados finales deben agruparse por día.

Hay muchas formas de filtrar por un rango de fechas:

  1. calcular manualmente la fecha y usar esta fecha en el filtro para obtener el rango deseado. Para esta pregunta, nos interesa filtrar en el rango de 30 días finalizando el 2019-07-27, por tanto el rango está entre el 2019-06-28 y 2019-07-27:
activity_date > '2019-06-27' AND activity_date <= '2019-07-27'

o usando el operados BETWEEN:

activity_date BETWEEN '2019-06-28' AND '2019-07-27'

Usamos ‘2019-06-28’ porque BETWEEN es inclusivo, de manera que las fechas de inicio y fin son incluidas.

  1. DATEDIFF(date1, date2): esta función regresa date1 - date2 expresada como el valor en días entre las dos fechas, asi que no necesidad para calcular la fecha exacta para el filtro:
DATEDIFF('2019-07-27', activity_date) < 30
AND
DATEDIFF('2019-07-27', activity_date) >= 0

la primera condición verifica que activity_date sea a lo mucho 30 días menor que ‘2019-07-27’. La segunda condición verifica que activity_date no se encuentre después de ‘2019-07-27’. Sin la segunda condición, una diferencia de días negativa es también < 30, y se incluiría en el resultado final.

Otra forma de usar DATEDIFF:

DATEDIFF('2019-07-27', activity_date) BETWEEN 0 AND 29
  1. DATE_SUB(date, INTERVAL expr unit): esta función realiza aritmética de fechas, si la sintaxis no soporta agregar o decrementar días directamente usando operadores como + o -:
activity_date BETWEEN date_sub('2019-07-27', INTERVAL 29 DAY)
AND '2019-07-27'
Algoritmo
  1. Filtrar las columnas que necesitamos: las fechas, y el número de usuarios distintos para cada fecha.
  2. Agregar el filtro por rango de fechas. En este punto debemos estar familizarizados con al menos uno de los métodos para filtrar la información por rango de fechas.
  3. Agrupar los resultados por activity_date.
SELECT
    activity_date AS day,
    COUNT(DISTINCT user_id) AS active_users
FROM
    Activity
WHERE
    DATEDIFF('2019-07-27', activity_date) < 30 AND DATEDIFF('2019-07-27', activity_date)>=0
GROUP BY 1

slackmart blog © 2024