2012-05-25 17 views
5

Ho le seguenti righe:Rimuovere le date contenute in altre date?

CREATE TABLE #TEMP (id int, name varchar(255), startdate datetime, enddate datetime) 
INSERT INTO #TEMP VALUES(1, 'John', '2011-01-11 00:00:00.000','2011-01-11 00:01:10.000') 
INSERT INTO #TEMP VALUES(2, 'John', '2011-01-11 00:00:20.000','2011-01-11 00:01:05.000') 
INSERT INTO #TEMP VALUES(3, 'John', '2011-01-11 00:01:40.000','2011-01-11 00:01:50.000') 
INSERT INTO #TEMP VALUES(4, 'Adam', '2011-01-11 00:00:40.000','2011-01-11 00:01:20.000') 
INSERT INTO #TEMP VALUES(5, 'Adam', '2011-01-11 00:00:45.000','2011-01-11 00:01:15.000') 

SELECT * FROM #TEMP 

DROP TABLE #TEMP 

sto cercando di rimuovere i record che hanno date di contenuti in altre date di ottenere i seguenti:

John 2011-01-11 00:00:00.000 2011-01-11 00:01:10.000 
John 2011-01-11 00:01:40.000 2011-01-11 00:01:50.000 
Adam 2011-01-11 00:00:40.000 2011-01-11 00:01:20.000 

Qualche suggerimento su come raggiungere questo obiettivo per un tavolo di circa 100.000 righe?

+0

tavolo-largo o per nome? –

+0

@JohnDewey: per nome – Legend

risposta

2

Questo dà il risultato desiderato:

DELETE T1 FROM #TEMP T1 
WHERE EXISTS(
    SELECT NULL FROM #TEMP T2 
    WHERE t1.id <> t2.id 
    AND  t1.name = t2.name 
    AND  t1.startdate >= t1.startdate 
    AND  t1.enddate <= t1.enddate 
) 

http://msdn.microsoft.com/en-us/library/ms188336.aspx

Edit: Ho appena notato che c'è un problema. Se ci sono duplicati (stesso inizio e fine), entrambi saranno eliminati (nessuno con l'approccio di John, anche con una sola data uguale). Quindi è necessario tener conto di questo:

DELETE T1 FROM #TEMP T1 
WHERE EXISTS(
    SELECT NULL FROM #TEMP T2 
    WHERE t1.id <> t2.id 
    AND  t1.name = t2.name 
    AND  t1.startdate > t2.startdate 
    AND  t1.enddate < t2.enddate 
    OR  t1.id <> t2.id 
    AND  t1.name = t2.name 
    AND  t1.startdate = t2.startdate 
    AND  t1.enddate < t2.enddate 
    OR  t1.id <> t2.id 
    AND  t1.name = t2.name 
    AND  t1.startdate > t2.startdate 
    AND  t1.enddate = t2.enddate 
    OR  t1.id > t2.id 
    AND  t1.name = t2.name 
    AND  t1.startdate = t2.startdate 
    AND  t1.enddate = t2.enddate 
) 
+0

Grazie. Forse mi manca qualcosa ma ho inserito questo record nell'output? – Legend

+0

@Legend: Modificato la mia risposta, è stata colpa mia :) –

+2

Sia John che Tim hanno delle belle domande. Pensavo che il join sarebbe stato più veloce ma certamente non lo è (non sto considerando gli indici). Ho caricato una tabella di prova con 2.384.001 di dati casuali e la versione di ESIST ha finito in 1:43 mentre ho interrotto la versione JOIN dopo 10 minuti. I piani di esecuzioni delle stime sono diversi e danno a EXIST la perdita di letture logiche mentre i piani effettivi per i record 2.384.001 hanno prodotto lo stesso piano se si prendono in considerazione solo gli operatori. Gli EXISTS possono interrompere la scansione dopo aver trovato una corrispondenza che è un grande vantaggio. – buckley

2
DELETE t1 FROM #TEMP t1 
INNER JOIN #TEMP t2 ON t2.startdate < t1.startdate AND t1.enddate < t2.enddate 
AND t1.name = t2.name 

risultati delle partite