2010-04-22 30 views
6

Tengo una tabla con registros por cada hora consecutiva. Cada hora tiene algún valor. Quiero una consulta T-SQL para recuperar los registros faltantes (horas faltantes, las lagunas). Entonces para el DDL a continuación, debería obtener un registro de la hora que falta 04/01/2010 a las 02:00 AM (suponiendo que el rango de fechas se encuentre entre el primer y el último registro). Usar SQL Server 2005. Prefiere una consulta basada en conjunto.Encontrar huecos (registros faltantes) en los registros de la base de datos usando SQL

DDL: 
CREATE TABLE [Readings](
    [StartDate] [datetime] NOT NULL, 
    [SomeValue] [int] NOT NULL 
) 
INSERT INTO [Readings]([StartDate], [SomeValue]) 
SELECT '20100401 00:00:00.000', 2 UNION ALL 
SELECT '20100401 01:00:00.000', 3 UNION ALL 
SELECT '20100401 03:00:00.000', 45 

Respuesta

15

el supuesto de que todos los registros son exactos horas:

WITH q(s, e) AS 
     (
     SELECT MIN(StartDate), MAX(StartDate) 
     FROM Readings 
     UNION ALL 
     SELECT DATEADD(hour, 1, s), e 
     FROM q 
     WHERE s < e 
     ) 
SELECT * 
FROM q 
WHERE s NOT IN 
     (
     SELECT StartDate 
     FROM Readings 
     ) 
OPTION (MAXRECURSION 0) 
+2

OMG .... que es fenomenal en cuanto a la rapidez con que escribió esto. Simplemente sorprendente. – Raja

+0

No puedo subir o bajar el voto esto porque estoy viendo este sql yendo ... gaaaaahhahahaaaa –

+0

Esa es una pregunta dulce. Nunca me di cuenta de que 'CON 'podría usarse recursivamente. – RedFilter

0

La única manera de que pudiera ver a resolver este sería crear una tabla con todas las fechas que espera tener, y luego realizar una unión a la tabla que desea comprobar si hay lagunas. Puede crear una función que tome 2 fechas devuelve una tabla con todas las fechas horarias entre esas dos fechas para que no tenga que crear una nueva tabla cada vez que desee encontrar todas las brechas en un período determinado.

Esta es una solución basada en un conjunto una vez que tiene la tabla con todas las fechas en ella. No creo que haya una forma de hacer esto sin generar primero una tabla con las fechas, y estoy bastante seguro de que no se puede hacer de una manera establecida.

Cuestiones relacionadas