2012-02-16 32 views
5

estoy casi enojando al tratar de resolver este problema:consulta SQL para contar los usuarios registrados por día

En mis usuarios de la aplicación pueden registrar y eliminar themselfes. La fecha de creación y la fecha de eliminación se conservan en la base de datos como una marca de tiempo. Necesito saber por cada día en un rango de días, cuántos usuarios registrados y no eliminados existieron en ese día.

Entonces, si tengo 10 usuarios existentes en 2012-02-01, un usuario que eliminó la cuenta el 2012-02-03, tres usuarios que se registraron el 2012-02-04 y dos usuarios eliminaron el 2012-02- 06, y consultar el número total de usuarios registrados desde 2012-02-01 hasta 2012-02-07 me gustaría conseguir un resultado como este:

 
day    total_users 
2012-02-01  10 
2012-02-02  10 
2012-02-03  9 
2012-02-04  12 
2012-02-05  12 
2012-02-06  10 
2012-02-07  10 

Así es como mi tabla de usuario simplificada se ve así:

user_id, nombre_usuario, created_at, deleted_at

no es ningún problema para obtener el número o f registrada y no los usuarios eliminados por un día específico (aquí 2012-02-01, que conseguirme un 10 en mi ejemplo):

select application.application_id as application_id, count(user.user_id) as user_total 
from application, user 
where application.application_id = user.application_id 
and date(user.created_at) <= '2012-02-01' 
and ((date(user.deleted_at) > '2012-02-01') or (user.deleted_at is null)) 

¿Quién tiene ni idea de cómo puedo crear una consulta (sin un cursor) que tendrá mi resultado esperado? Mi base de datos es MySQL 5.0.51 en Debian.

Gracias de antemano Marcus

Respuesta

2

Si usted tiene una tabla con una lista de fechas en el mismo (llamado algo así como el calendario), se puede utilizar una consulta como esta:

select c.calendar_date, count(*) user_total 
from calendar c 
left join user u 
     on date(u.created_at) <= c.calendar_date and 
      (date(u.deleted_at) > c.calendar_date or u.deleted_at is null) 
group by c.calendar_date 

Si no tiene una tabla con una lista de fechas, puede simular una con la siguiente consulta:

select * from 
(select adddate('1970-01-01',t4.i*10000 + t3.i*1000 + t2.i*100 + t1.i*10 + t0.i) calendar_date from 
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t0, 
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t1, 
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t2, 
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t3, 
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t4) v 
where calendar_date between ? /*start of date range*/ and ? /*end of date range*/ 
+0

Muchas gracias, ¡esto funciona a la perfección! Solo tuve que reemplazar la "i" en cada línea con t0, t1, etc., creo que esta es la culpa de mi antiguo servidor MySQL. –

+0

@MarcusMuench: Vaya, mi culpa. He corregido la consulta, gracias. –

2
SELECT date(user.created_at) as "creation_date", count(user.user_id) as "user_total" 
FROM application a 
INNER JOIN user u ON a.application_id = u.application_id 
WHERE date(user.created_at) <= '2012-02-01' 
AND ((date(user.deleted_at) > '2012-02-01') or (user.deleted_at is null)) 
GROUP BY date(user.created_at) 
ORDER BY date(user.created_at) ASC 
+0

+1. @ user1214154, tenga en cuenta que esto no mostrará las fechas que no tienen usuarios registrados en ese día con 0 como recuento. saldrá solo días que existan en la tabla – talereader

+0

Esto no devolverá el número de usuarios registrados por cada día; en su lugar, devolverá el número de usuarios que se registraron * en * cada día. Teniendo en cuenta los datos de muestra descritos en la pregunta, no producirá el resultado requerido; en su lugar, generará una cantidad de usuarios y fechas anteriores al 2012-02-01 (sumando hasta 10 usuarios en total), y nada después de 2012- 02-01. –

Cuestiones relacionadas