2008-10-08 45 views
7

¿Puede indicarme el SQL para dividir los intervalos de fechas cuando se superponen?SQL Rango de fechas dividido

Data (datos de muestra con un intervalo de fechas y posiblemente otras columnas):

Col1 FromDate ToDate 
1. 1 1/1/2008 31/12/2010 
2. 1 1/1/2009 31/12/2012 
3. 1 1/1/2009 31/12/2014 

Salida:

Col1 From Date ToDate 
1. 1  1/1/2008 31/12/2008 (from row 1 above) 
2. 1  1/1/2009 31/12/2010 (from rows 1,2 and 3 above) 
3. 1  1/1/2011 31/12/2012 (from rows 2 and 3 above) 
4. 1  1/1/2013 31/12/2014 (from row 3 above) 
+0

Ok, no tengo la respuesta completa, pero aquí hay algunos puntos a considerar. 1. El primer bloque de tiempo es select min (FromDate) del grupo de tablas por FromDate'print ("código de muestra"); '2. Luego, el final del primer bloque es select min (FromDate) del grupo de tablas por FromDate donde FromDate> "inicio de bloque" 3. Repita según sea necesario. :) – Craig

Respuesta

6

Esto debería hacer el truco (dialecto MySQL, pero fácilmente adaptable)

Configuración inicial

SQL query: SELECT * FROM `test` LIMIT 0, 30 ; 
Rows: 3 
start  end 
2008-01-01 2010-12-31 
2009-01-01 2012-12-31 
2009-01-01 2014-12-31 

consulta

SELECT 
    `start` , min(`end`) 
FROM (
    SELECT t1.start, t2.end 
    FROM test t1, test t2 
    WHERE t1.start < t2.end 
    UNION 
    SELECT t1.end + INTERVAL 1 DAY , t2.end 
    FROM test t1, test t2 
    WHERE t1.end + INTERVAL 1 DAY < t2.end 
    UNION 
    SELECT t1.start, t2.start - INTERVAL 1 DAY 
    FROM test t1, test t2 
    WHERE t1.start < t2.start - INTERVAL 1 DAY 
) allRanges 
GROUP BY `start` 

Resultado

start  min(`end`) 
2008-01-01 2008-12-31 
2009-01-01 2010-12-31 
2011-01-01 2012-12-31 
2013-01-01 2014-12-31 
2

respuesta de Skliwz adaptada para SQL Server:

DECLARE @DateTest TABLE 
(
    FromDate datetime, 
    ToDate datetime 
) 

insert into @DateTest (FromDate, ToDate) 
(
select cast('1/1/2008' as datetime), cast('12/31/2010' as datetime) 
union 
select cast('1/1/2009' as datetime), cast('12/31/2012' as datetime) 
union 
select cast('1/1/2009' as datetime), cast('12/31/2014' as datetime) 
) 

SELECT 
    FromDate , min(ToDate) 
FROM (
    SELECT t1.FromDate, t2.ToDate 
    FROM 
    @DateTest t1, 
    @DateTest t2 
    WHERE t1.FromDate < t2.ToDate 

    UNION 

    SELECT dateadd(DAY, 1, t1.ToDate), t2.ToDate 
    FROM 
    @DateTest t1, 
    @DateTest t2 
    WHERE dateadd(DAY, 1, t1.ToDate) < t2.ToDate 
) allRanges 
group by FromDate 
Cuestiones relacionadas