Crear reporte con sql server organizado por horas autocompletando filas

Suponiendo una tabla con esta estructura:

fecha                                Respuesta        
2012/02/01 XX:01            a              
2012/02/01 XX:01            b              
2012/02/01 XX:01            a              
2012/02/01 XX:01            b         
...
...
..
Muchos registros
...
...
Y suponiendo que no hay registros en la hora 2 respuesta b y no hay hora 3 respuesta a
    

Queremos lo siguiente como resultado del Store procedure:

Hora         Respuesta        Cantidad
1             a                              10
1             b                              15
2             a                                4
2             b                               0  <-- fila autocompletada porque no hay registros
3             a                               0  <-- fila autocompletada porque no hay registros
3             b                              6

El procedimiento para hacer una consulta con la cual pueda obtener un reporte por el conteo de filas, y que las horas que no existan en la bd se autocompleten este sería el query:

DECLARE @minHour INT
DECLARE @maxHour INT

DECLARE @DATEFROM DATETIME
SET @DATEFROM = '2013-09-15 00:00:56.330'

DECLARE @DATETO DATETIME
SET @DATETO = '2013-09-15 23:59:56.330'

SELECT TOP 1 @minHour = DATEPART(hh,FechaAAnalizar) FROM TablaReporte OPE
WHERE OPE.FechaAAnalizar > @DATEFROM
and  OPE.FechaAAnalizar < @DATETO
GROUP BY DATEPART(hh,FechaAAnalizar)
ORDER BY DATEPART(hh,FechaAAnalizar) ASC

SELECT TOP 1 @maxHour = DATEPART(hh,FechaAAnalizar) FROM TablaReporte OPE
WHERE OPE.FechaAAnalizar > @DATEFROM
and  OPE.FechaAAnalizar < @DATETO
GROUP BY DATEPART(hh,FechaAAnalizar)
ORDER BY DATEPART(hh,FechaAAnalizar) DESC


--SELECT DATEPART(hh,FechaAAnalizar), idTipoDeRespuesta, count(1) FROM TablaReporte OPE
--WHERE OPE.FechaAAnalizar > @DATEFROM
--and  OPE.FechaAAnalizar < @DATETO
--GROUP BY DATEPART(hh,FechaAAnalizar), idTipoDeRespuesta
--ORDER BY DATEPART(hh,FechaAAnalizar), idTipoDeRespuesta

IF OBJECT_ID('tempdb..#tableHours') IS NOT NULL DROP TABLE #tableHours

;WITH CTE as
(SELECT 1 i UNION ALL
SELECT i+1 i FROM CTE WHERE i < 5)
SELECT DATEPART(HH, DATEADD(HH, @minHour + i, @DATETO)) 'hour' INTO #tableHours from CTE

IF OBJECT_ID('tempdb..#tableTypes') IS NOT NULL DROP TABLE #tableTypes

SELECT idTipoDeRespuesta 'type' INTO #tableTypes FROM TablaReporte OPE
WHERE OPE.FechaAAnalizar > @DATEFROM
and  OPE.FechaAAnalizar < @DATETO
GROUP BY idTipoDeRespuesta

--test combinaciones tipos con horas
/*
SELECT [hour], [type] FROM #tableHours, #tableTypes
ORDER BY [hour], [type]
*/

SELECT * FROM
(
--Tabla de datos reales
SELECT DATEPART(hh,FechaAAnalizar) 'hour', idTipoDeRespuesta 'type', count(1) 'Value' FROM TablaReporte OPE
WHERE OPE.FechaAAnalizar > @DATEFROM
and  OPE.FechaAAnalizar < @DATETO
GROUP BY DATEPART(hh,FechaAAnalizar), idTipoDeRespuesta

UNION
--Agregar combinaciones que no se encuentren en los datos reales
SELECT [hour], [type] , 0 FROM
(
SELECT [hour], [type] FROM #tableHours, #tableTypes
) AS Combinaciones
WHERE CAST([hour] AS VARCHAR(30)) +  CAST([type] AS VARCHAR(30)) NOT IN
(
SELECT CAST(DATEPART(hh,FechaAAnalizar) AS VARCHAR(30)) + CAST(idTipoDeRespuesta  AS VARCHAR(30))  FROM TablaReporte OPE
WHERE OPE.FechaAAnalizar > @DATEFROM
and  OPE.FechaAAnalizar < @DATETO
GROUP BY DATEPART(hh,FechaAAnalizar), idTipoDeRespuesta
)
) AS ResultFinal
ORDER BY 'hour', 'type'

Sean felices! :) Y siéntanse libres de opinar ;)

No hay comentarios:

Publicar un comentario