2011-03-06 8 views
8

मैं इस तरह दोनों आंशिक रूप से और पूरी तरह से अतिव्यापी दिनांक से मिलकर तिथि सीमाओं का एक सेट, है:को हटा दें और ओवरलैपिंग तारीख को कम पर्वतमाला

UserID StartDate EndDate 
====== ========== ========== 
1  2011-01-01 2011-01-02 <- A 
1  2011-01-01 2011-01-10 <- A 
1  2011-01-08 2011-02-15 <- A 
1  2011-02-20 2011-03-10 <- B 
2  2011-01-01 2011-01-20 <- C 
2  2011-01-15 2011-01-25 <- C 

T-SQL का उपयोग करना, मैं डेटा का एक नया सेट बनाना चाहेंगे प्रति उपयोगकर्ता, सफाया अतिव्यापी डेटा, पर्वतमाला का विस्तार और अनावश्यक डेटा जहां जरूरत को हटाने, कुछ इस तरह है, जिसके परिणामस्वरूप के साथ:

UserID StartDate EndDate 
====== ========== ========== 
1  2011-01-01 2011-02-15 ('A', three rows combined, extending the range) 
1  2011-02-20 2011-03-10 ('B', no change, no overlaps here) 
2  2011-01-01 2011-01-25 ('C', two rows combined) 

कर्सर ठीक अगर जरूरत है, लेकिन अगर मैं उन्हें बिना ऐसा कर सकते हैं और भी बेहतर होगा।

+0

के साथ बदलें @t क्या एसक्यूएल सर्वर, 2005+ के संस्करण? – RichardTheKiwi

+0

हां, एसक्यूएल सर्वर 2005+। –

उत्तर

12

एसक्यूएल सर्वर 2005+

-- sample table with data 
declare @t table(UserID int, StartDate datetime, EndDate datetime) 
insert @t select 
1, '20110101', '20110102' union all select 
1, '20110101', '20110110' union all select 
1, '20110108', '20110215' union all select 
1, '20110220', '20110310' union all select 
2, '20110101', '20110120' union all select 
2, '20110115', '20110125' 

-- your query starts below 

select UserID, Min(NewStartDate) StartDate, MAX(enddate) EndDate 
from 
(
    select *, 
     NewStartDate = t.startdate+v.number, 
     NewStartDateGroup = 
      dateadd(d, 
        1- DENSE_RANK() over (partition by UserID order by t.startdate+v.number), 
        t.startdate+v.number) 
    from @t t 
    inner join master..spt_values v 
     on v.type='P' and v.number <= DATEDIFF(d, startdate, EndDate) 
) X 
group by UserID, NewStartDateGroup 
order by UserID, StartDate 

नोट्स के लिए:

  1. अपनी मेज नाम
+0

ग्रेट सामान! एक जादू की तरह काम करता है! मुझे ** DENSE_RANK() ** के उपयोग को देखना होगा, जो मेरे लिए नया था। धन्यवाद! –

+0

यह उल्लेखनीय है कि तारीख के लिए 'मास्टर .. spt_values' द्वारा लौटाई गई पंक्तियों की संख्या से अधिक अवधि के लिए यह काम नहीं करेगा। इस मामले में, आप एक बड़ी विंडो आकार देने के लिए उस तालिका में शामिल हो सकते हैं। –

+0

कुछ DENSE_RANK() दस्तावेज़: https://docs.microsoft.com/en-us/sql/t-sql/functions/dense-rank-transact-sql – Westy92

संबंधित मुद्दे