2011-01-26 12 views
11

Tengo el siguiente código, que agrupa algunos eventos (AAAA-MM-DD HH: MM: SS) en semanas que se muestran como, por ejemplo, "Y: 2010 - Semana: 50".¿Grupo por semana, cómo obtener semanas vacías?

SELECT DATE_FORMAT(date, 'Y:%X - Week:%V') AS regweek, COUNT(*) as number 

funciona bien, pero me gustaría volver todas las semanas, incluso aquellas en las que no se realiza ningún evento.

Si ningún caso se ha registrado en la tercera semana, en el momento me sale:

week 1: 10 
week 2: 1 
week 4: 2 

me gustaría llegar:

week 1: 10 
week 2: 1 
week 3: 0 
week 4: 2 
+0

¿Quieres * todas * semanas desde cuándo? El comienzo de los tiempos? – thkala

+1

Todas las semanas desde el momento en que ocurrió el primer evento o quizás los últimos N meses también estarían bien. Solo debería ser un período de tiempo "continuo" – Danilo

Respuesta

8

SQL no puede devolver filas que no existen en alguna mesa Para obtener el efecto que desea, necesitará una tabla Weeks (WeekNo INT) con una fila por semana posible del año (que, IIRC, es 53 o 54 semanas posibles, dependiendo de cómo cuente).

A continuación, unirse a esta mesa a los resultados regulares con una combinación externa para obtener las semanas extra añadido en

SELECT DATE_FORMAT(date, 'Y:%X - Week:%V') AS regweek, COUNT(date) as number 
    FROM YourTable RIGHT OUTER JOIN Weeks ON WEEK(YourTable.date) = Weeks.WeekNo 

[Actualización]:. Nota al usuario de COUNT (fecha) en lugar de COUNT (*) . SQL no incluirá valores NULL en la columna de fecha al sumar el COUNT. Como las semanas faltantes no tendrán fechas, esto le dará correctamente 0 eventos para esas semanas.

+0

Gracias por la sugerencia. Estoy tratando de seguir de esta manera, pero la combinación correcta devolverá el número = 1 para una semana específica, incluso si no hubo ningún evento en esa semana, ¿verdad? – Danilo

+1

Debe cambiar COUNT (*) en COUNT (fecha). Como la fecha será NULL para las semanas "faltantes", no se incluirá en el recuento. Actualizaré mi respuesta. –

+0

¡maravilloso! Si no me equivoco, su respuesta también necesita un "grupo por Weeks.WeekNo" para funcionar correctamente – Danilo

0

Este es el tipo de problema para el que se hacen los números/tablas de conteo, simplemente una tabla simple que cuenta de 0 a lo que sea. Son útiles en general, siempre recomendaría agregarlos a su base de datos.

Con esto puede generar una lista de semanas sobre la marcha con relativa facilidad sin necesidad de una tabla de semanas precalculada específica (para no necesitar una gran mesa o preocuparse por quedarse sin semanas), luego se unió eso contra su lista de citas para mostrar todas las semanas con una cita en ellas.

Para un comienzo rápido:

declare @min datetime 
set  @min ='2010-01-01' 

select 
    dateadd(wk, number, @min) as weekDate 
from 
    numbers 
where 
    number between 0 and datediff(wk,@min,getdate()) 

con

1

Al final me decidí a resolver el problema de la siguiente manera, crear una tabla temporal para las semanas y utilizando el código que se encuentra en el responde aquí arriba.

CREATE TEMPORARY TABLE weeks (
     id INT 
     ); 
INSERT INTO weeks (id) VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11), (12), (13), (14), (15), (16), (17), (18), (19), (20), (21), (22), (23), (24), (25), (26), (27), (28), (29), (30), (31), (32), (33), (34), (35), (36), (37), (38), (39), (40), (41), (42), (43), (44), (45), (46), (47), (48), (49), (50), (51), (52), (53), (54); 
SELECT 
w.id, COUNT(c.issuedate) as numberPerWeek 
FROM tableName c RIGHT OUTER JOIN weeks w ON WEEK(c.issuedate) = w.id group by w.id; 
+0

En realidad, estás creando una tabla de números temporales de esta manera para producir tu resultado :-) Son una buena técnica general, bien vale la pena seguir leyendo. – eftpotrm

Cuestiones relacionadas