2012-09-19 12 views
7

मेरे पास अनुपस्थिति विवरण नामक एक तालिका है और मैं अनुक्रमिक तिथियों को समूहबद्ध करना चाहता हूं। इधर, डेटासमूह अनुक्रमिक तिथियों के लिए SQL सर्वर क्वेरी

है
EID  AbsenceType AbsenceStartDate    AbsenceEndDate 
769  Holiday  2012-06-25 00:00:00.000   2012-06-25 23:59:59.000 
769  Holiday  2012-06-26 00:00:00.000   2012-06-26 23:59:59.000 
769  Holiday  2012-09-03 00:00:00.000   2012-09-03 23:59:59.000 
769  Holiday  2012-09-04 00:00:00.000   2012-09-04 23:59:59.000 
769  Holiday  2012-09-05 00:00:00.000   2012-09-05 23:59:59.000 
769  Holiday  2012-09-06 00:00:00.000   2012-09-06 23:59:59.000 
769  Holiday  2012-09-07 00:00:00.000   2012-09-07 23:59:59.000 

परिणाम मैं प्राप्त करने के लिए कोशिश कर रहा हूँ

EID  AbsenceType AbsenceStartDate   AbsenceEndDate 
769  Holiday  2012-06-25 00:00:00.000   2012-06-26 23:59:59.000 
769  Holiday  2012-09-03 00:00:00.000   2012-09-07 23:59:59.000 

किसी भी मदद की बहुत सराहना कर रहा है।

+0

आप हेडर से अनुपस्थित टाइप प्रकार को हटा दें या इस कॉलम के लिए मान जोड़ें। – Vikdor

+0

@ विकदर - यह सच है कि मैं अनुपस्थिति कारण कॉलम को हटाने के लिए भूल गया। उसके लिए धन्यवाद। – user1682461

+0

@podiluska - मैंने अभी तक कोई प्रश्न लिखना शुरू नहीं किया है। बस पॉइंटर्स की तलाश में। – user1682461

उत्तर

0

यदि मैं आपका प्रश्न सही ढंग से समझ गया तो आप अपने रिकॉर्ड में निरंतर समय अंतराल खोजना चाहते हैं।
मुख्य समस्या की पहचान की जाएगी क्या वास्तव में निरंतर समय अंतराल का गठन किया:
आप

date1.09:00 to date1.18:00 
date2.09:00 to date2.18:00 

के किसी भी क्रम जहां date2 के बाद date1 माना जा सकता है एक अगले कार्य दिवस है से काम पर अनुपस्थिति में देख रहे हैं निरंतर।

आपके मामले में यह अपेक्षाकृत आसान है, लेकिन आप इसे एक प्रश्न में नहीं कर पाएंगे। कम से कम मैं इसे अभी करने का तरीका नहीं सोच सकता।

पीएस "पॉडिलुस्का" द्वारा सुझाए गए "द्वीप समूह और अंतराल" एल्गोरिदम आपको एक प्रश्न/संग्रहीत प्रक्रिया में लिखने में मदद करेगा।

1

मैं यह कर देंगी:

  1. अभाव तिथियों के क्रम की सूची को पहचानें।

    SELECT 
        ad1.EID, ad1.StartDate, ad2.EndDate 
    FROM 
        AbsenceDetails ad1 
        JOIN AbsenceDetails ad2 
        ON ad1.EID = ad2.EID 
    WHERE 
        DATEDIFF(ss, ad1.EndDate, ad2.StartDate) = 1 
    

    परिणाम इस प्रकार होगा:

    769 2012-06-25 00:00:00.000 2012-06-26 23:59:59.000 
    769 2012-09-03 00:00:00.000 2012-09-04 23:59:59.000 
    769 2012-09-04 00:00:00.000 2012-09-05 23:59:59.000 
    769 2012-09-05 00:00:00.000 2012-09-06 23:59:59.000 
    769 2012-09-06 00:00:00.000 2012-09-07 23:59:59.000 
    
  2. सूची के माध्यम से दोहराएं और प्रत्येक खंड के प्रारंभ और समाप्ति अवधि की पहचान। ऐप परत पर यह बेहतर होता है।

4

मैंने मुख्य समस्या को अलग करने के लिए अपने परिदृश्य को सरल बना दिया है। के अंतराल के साथ इस तालिका supose करते हैं:

with ns as (
select 1 as n union 
select 2 as n union 
select 3 as n union 
select 8 as n union --gap 
select 9 as n) 
select * 
into #ns 
from ns; 

अब, परिणाम आप के लिए उम्मीद कर रहे हैं है:

ini fi 
--- -- 
1 3 
8 9 

इस मैं इस तरह से डेटा की मालिश परिणाम प्राप्त करने के लिए: पहले मैं शुरुआत के साथ दो दृश्य बना और अंत अवधि और दूसरा, मैं अंतिम परिणाम प्राप्त करने के लिए दोनों विचारों में शामिल हूं। सूचना है कि मैं यह स्वयं के साथ तालिका में शामिल होने शुरू होता है पता लगाने के लिए और समाप्त होता है अवधि:

with 
inis as          -- identifying start periods 
(
    select n1.n 
    from #ns n1 
    left outer join #ns n2 
     on n1.n = n2.n + 1 
    where n2.n is null 
    ), 
fis as          -- identifying ends periods 
( 
    select n1.n 
    from #ns n1 
    left outer join #ns n2 
     on n1.n = n2.n - 1 
    where n2.n is null 
    ) 
select inis.n as ini, min(fis.n) as fi -- joining starts and ends 
from inis 
inner join fis 
    on inis.n <= fis.n 
group by inis.n 
; 

आप अपने डेटा और डेटा प्रकार के लिए इस तकनीक हस्तांतरण कर सकते हैं। यदि आपके पास कोई समस्या अनुवाद क्वेरी है तो पूछने के लिए स्वतंत्र रहें।

Check query and results.

4

यहाँ समाधान है कि मेरे लिए काम किया है।

SELECT EID, AbsenceType, MIN(AbsenceStartDate) AS AbsenceStartDate, MAX(AbsenceEndDate) AS AbsenceEndDate 
FROM (SELECT EID, AbsenceType, AbsenceStartDate, AbsenceEndDate, 
     DATEADD(dd, - ROW_NUMBER() OVER (PARTITION BY EID, AbsenceType ORDER BY EID,AbsenceStartDate), AbsenceStartDate) 
     FROM AbsenceDetails 
     GROUP BY EID,AbsenceType,AbsenceStartDate,AbsenceEndDate 
    ) a(EID, AbsenceType, AbsenceStartDate, AbsenceEndDate, Grp) 
GROUP BY EID, AbsenceType, Grp; 
+0

+1 यह एक बहुत अच्छा जवाब है। अगली बार कोड को प्रारूपित करना याद रखें –

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