2008-10-08 10 views
7

क्या आप मुझे एसक्यूएल को बता सकते हैं कि जब वे ओवरलैप करते हैं तो तिथि सीमाओं को विभाजित करने के लिए?एसक्यूएल तिथि रेंज स्प्लिट

डेटा (एक तिथि सीमा के साथ नमूना डेटा और संभवतः अन्य स्तंभों):

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 

आउटपुट:

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

ठीक है, मैं पूरा जवाब नहीं है, लेकिन यहाँ कुछ बिंदुओं पर विचार करने के लिए कर रहे हैं। 1. समय का पहला ब्लॉक तालिका समूह से FromDate'print ("कोड नमूना") द्वारा न्यूनतम समूह (सेडेटेट) का चयन करता है; '2. फिर पहले ब्लॉक का अंत तालिका समूह से सेव (FromDate) को FromDate से चुनें जहां से FromDate> "ब्लॉक की शुरुआत" 3. आवश्यकतानुसार दोहराना। :) – Craig

उत्तर

6

यह चाल (MySQL बोली, लेकिन आसानी से अनुकूलनीय)

करना चाहिए

आरंभिक सेटअप

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 

क्वेरी

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` 

परिणाम

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

Skliwz के जवाब एसक्यूएल सर्वर के लिए अनुकूलित:

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 
संबंधित मुद्दे