2011-05-13 14 views
8

Estoy escribiendo una consulta para devolver la cantidad de publicaciones de blog escritas por día durante un cierto período de tiempo. Mi problema surge cuando no hay registros de un blog para un día determinado. Con mi consulta, el resultado de ese día simplemente se salta por completo.MySQL GROUP BY fecha - cómo devolver resultados cuando no hay filas

Aquí es mi consulta:

SELECT DATE(`posted`), COUNT(`id`) 
    FROM `blogs` WHERE `status` = 'active' 
    && `posted` BETWEEN `2011-01-01` AND `2011-05-01` 
    GROUP BY DATE(`posted`) 

Devuelve algo similar a:

count | date 
_________________ 
2  | 2011-01-01 
5  | 2011-01-02 
1  | 2011-01-04 

en cuenta que no se encuentra 2011-01-03, ya que no tiene ninguna entrada.

¿Cómo puedo mostrar esos días con 0 publicaciones?

Respuesta

6

que había necesidad de tener una tabla que contiene todas las fechas que vas a preguntar otra vez, y hacer algo en la línea de ...

SELECT DATE(D.`thedate`), COUNT(`id`) 
FROM `datetable` D 
LEFT JOIN `blogs` B 
ON B.`posted` = D.`thedate` 
WHERE `status` = 'active'  
&& D.`thedate` BETWEEN `2011-01-01` AND `2011-05-01`  
GROUP BY DATE(D.`thedate`) 
+0

¿Cómo manejaría esto de una manera dinámica? Me gustaría tener estadísticas actualizadas y me gustaría poder elegir fechas al azar. – johnnietheblack

+0

@johnnietheblack: solo asegúrese de que su tabla de fechas contenga un rango lo suficientemente grande como para cubrir todas las consultas posibles, ya que todavía está filtrando las fechas en la cláusula WHERE, si la tabla de fechas contiene todas las fechas de 1900 a 2100 (por ejemplo, un poco excesivo) realmente no importará, ¡solo asegúrate de indexar la columna de fecha en esta tabla! –

0

para crear la tabla que contiene las fechas (tomado de http://www.artfulsoftware.com/infotree/queries.php?&bw=1280#95):

-- Create a dummy view with 3 rows 
create or replace view v3 as select 1 n union all select 1 union all select 1; 
-- create a second dummy view with 10 rows 
-- By making joins with this view, you can create 100, 1000, ... rows 
create or replace view v as select 1 n from v3 a, v3 b union all select 1; 
-- counter 
set @n = 0; 
-- create date table 
drop table if exists datetable; 
create table datetable(thedate date primary key); 
-- populate from start date 
insert into datetable select cast('1970-1-1' + interval @n:[email protected]+1 day as date) as thedate 
from v a, v b, v c, v d, v e, v;