Solución
Base de datos
Vista general
Las dos claves para resolver esta pregunta son:
- filtrar en un rango especÃfico de fechas
- 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:
- 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.
DATEDIFF(date1, date2)
: esta función regresadate1 - 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
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
- Filtrar las columnas que necesitamos: las fechas, y el número de usuarios distintos para cada fecha.
- 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.
- 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