2012-05-25 23 views
5

Tengo las siguientes filas:Eliminar las fechas contenidas en otras fechas?

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 

Estoy tratando de eliminar los registros que tienen fechas contenidas en otras fechas para obtener los siguientes:

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 

¿Alguna sugerencia sobre cómo lograr esto para una mesa de aproximadamente 100K filas?

+0

o por nombre de toda la mesa? –

+0

@JohnDewey: Por nombre – Legend

Respuesta

2

Esto da el resultado deseado:

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

Editar: Acabo de cuenta de que hay un problema. Si hay duplicados (las mismas fechas de inicio y finalización), ambos se eliminarán (ninguno con el enfoque de John, incluso con una sola fecha igual). Así que hay que tener esto en cuenta:

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

Gracias. Tal vez me falta algo, ¿pero puse este disco en la salida? – Legend

+0

@Legend: Editado mi respuesta, fue mi culpa :) –

+2

Tanto John como Tim tienen buenas consultas. Realmente pensé que la unión sería más rápida, pero ciertamente no (no estoy considerando los índices). Cargué una tabla de prueba con 2.384.001 datos aleatorios y la versión EXIST finalizó en 1:43 mientras detenía la versión JOIN después de 10 minutos. Los planes de ejecución de estimación son diferentes y le dan a EXIST menos lecturas lógicas, mientras que los planes reales para los registros 2.384.001 producen el mismo plan si solo se tienen en cuenta los operadores. Los EXISTS pueden detener el escaneo después de encontrar una coincidencia, lo que es una gran ventaja. – 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 

resultados de los partidos