2010-04-22 17 views
6

Ho una tabella con record per ogni ora consecutiva. Ogni ora ha qualche valore. Voglio una query T-SQL per recuperare i record mancanti (ore mancanti, le lacune). Quindi, per il DDL di seguito, dovrei ottenere un record per l'ora mancante 04/01/2010 02:00 (supponendo che l'intervallo di date sia compreso tra il primo e l'ultimo record). Utilizzo di SQL Server 2005. Preferire una query basata su set.Trovare lacune (record mancanti) nei record del database utilizzando 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 

risposta

15

Partendo dal presupposto che tutti i record sono ore esatte:

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 .... che è fenomenale di come veloce è stato scritto da. Semplicemente fantastico. – Raja

+0

Non posso salire o scendere votare perché sto guardando questo sql andando .. gaaaaahhahahaaaa –

+0

Questa è una domanda dolce. Non ho mai realizzato che 'WITH' potesse essere usato ricorsivamente. – RedFilter

0

L'unico modo ho potuto vedere per risolvere questo sarebbe quello di creare una tabella con tutte le date si aspetta di avere, e quindi eseguire un join alla tabella che si desidera verificare la presenza di lacune. È possibile creare una funzione che richiede 2 date restituisce una tabella con tutte le date orarie tra queste due date in modo da non dover creare una nuova tabella per ogni volta che si desidera trovare tutte le lacune in un determinato periodo.

Questa è una soluzione basata su set una volta che hai la tabella con tutte le date in esso. Non penso che ci sia un modo per farlo senza prima generare un tavolo con le date, e sono abbastanza sicuro che non puoi farlo in un modo basato su un set.

Problemi correlati