2009-06-22 13 views
6

मैं है दिनांकों (दिन/माह/वर्ष) मेरी डेटाबेस में घटनाओं से मेल खाते के निम्नलिखित सेट के बीच अतिव्यापी दिनांक श्रेणी:गणना लापता तिथि सीमाओं तथा दो तिथियों

 
eventId  startDate  endDate 
1   02/05/2009 10/05/2009 
2   08/05/2009 12/05/2009 
3   10/05/2009 12/05/2009 
4   21/05/2009 21/05/2009 
5   25/05/2009 NULL 
6   01/06/2009 03/06/2009 

घटनाओं एक आरंभ और समाप्ति तिथि है (समय कोई फर्क नहीं पड़ता) और एक पूर्ण अंतराल का मतलब है कि घटना अभी भी प्रगति पर है।

मैं निर्धारित करने के लिए क्या चाहते हैं दो मनमाना दिनांकों जहां एक था) किसी भी स्थिति और ख) की घटनाओं अतिव्यापी थे के बीच तारीखों के पर्वतमाला है।

 
no event: 01/04/2009 - 01/05/2009 
overlap : 08/05/2009 - 10/05/2009 
overlap : 10/05/2009 - 12/05/2009 
no event: 13/05/2009 - 20/05/2009 
no event: 22/05/2009 - 24/05/2009 
overlap : 01/06/2009 - 03/06/2009 

ध्यान दें कि दो आसन्न ओवरलैप पर्वतमाला एक के रूप में स्वीकार्य होगा: 30/06/2009 मैं निम्नलिखित परिणाम की उम्मीद करेंगे -

01/04/2009 के एक इनपुट समय अवधि के लिए

तो परिणाम।

किसी को भी कृपया मुझे किसी SQL एल्गोरिथ्म इस परिणाम सेट उत्पन्न करने के लिए के साथ मदद कर सकते हैं?

संपादित करें: लक्ष्य मंच डेटाबेस, SQL सर्वर 2005 दिनांक 2009/10/05 00:00:00 के रूप में दर्ज किया जाता है जिसका अर्थ है कि घटना 2009/10/05 00:00:00 और के बीच कुछ समय समाप्त हो गया 10/5/2009 23:59:59। शुरुआत तिथियों के लिए भी यही सच है। इनपुट तिथि सीमा को भी 01/04/2009 00:00:00 - 30/06/2009 23:59:59 के रूप में पढ़ा जा सकता है।

+1

जो डेटाबेस मंच (रों) आप इस क्वेरी चलाने किया जाएगा? –

उत्तर

4

यह SQL Server में अन्तर्विभाजक timespans समतल समारोह का एक छोटा परिवर्तन हो:

यह दुर्लभ मामलों में से एक है जब कर्सर आधारित दृष्टिकोण SQL Server में तेजी से एक है सेट-आधारित एक:


CREATE FUNCTION mytable(@p_from DATETIME, @p_till DATETIME) 
RETURNS @t TABLE 
     (
     q_type VARCHAR(20) NOT NULL, 
     q_start DATETIME NOT NULL, 
     q_end DATETIME NOT NULL 
     ) 
AS 
BEGIN 
     DECLARE @qs DATETIME 
     DECLARE @qe DATETIME 
     DECLARE @ms DATETIME 
     DECLARE @me DATETIME 
     DECLARE cr_span CURSOR FAST_FORWARD 
     FOR 
     SELECT startDate, endDate 
     FROM mytable 
     WHERE startDate BETWEEN @p_from AND @p_till 
     ORDER BY 
       startDate 
     OPEN cr_span 
     FETCH NEXT 
     FROM cr_span 
     INTO @qs, @qe 
     SET @ms = @qs 
     SET @me = @qe 
     WHILE @@FETCH_STATUS = 0 
     BEGIN 
       FETCH NEXT 
       FROM cr_span 
       INTO @qs, @qe 
       IF @qs > @me 
       BEGIN 
         INSERT 
         INTO @t 
         VALUES ('overlap', @ms, @me) 
         INSERT 
         INTO @t 
         VALUES ('gap', @me, @qs) 
         SET @ms = @qs 
       END 
       SET @me = CASE WHEN @qe > @me THEN @qe ELSE @me END 
     END 
     IF @ms IS NOT NULL 
     BEGIN 
       INSERT 
       INTO @t 
       VALUES (@ms, @me) 
     END 
     CLOSE cr_span 
     RETURN 
END 
GO 

यह समारोह एक रेंज में अन्तर्विभाजक पर्वतमाला से प्रत्येक सन्निहित सेट संपीड़ित करता है, और दोनों रेंज और निम्न खाई देता है।

+0

क्या क्वास्नोई द्वारा किसी समस्या का समाधान है? यदि हां, तो फ़ंक्शन में डेटा तालिका का नाम क्या है। –

+0

+1 धन्यवाद ....... –

1

वास्तव में समझ समस्या को हल करने की कोशिश कर रहे बिना, यहाँ करने के लिए अपने समाधान है मेरे सिर के ऊपर से कुछ समस्या:

  1. बनाएं तालिका समारोह (यूडीएफ) "सभी तिथियों" है कि होगा एक साल में सभी तिथियां वापस करें।
  2. सभी तिथियों where the date is between event's start and end dates के भीतर शामिल होने घटनाओं से अलग तिथियों (एक घटना पंक्ति के रूप में कई पंक्तियों के रूप में उसमें दिन हैं बन जाएगा) करने के लिए अपने घटनाओं कन्वर्ट ... मूल eventID रखें।
  3. अंतराल या यादों को खोजने के लिए सभी तिथियों (दोबारा) के साथ ईवेंट-तिथियों का बाहरी हिस्सा शामिल करें।
  4. ओवरलैप को खोजने के लिए where dates are same but eventId is not पर खुद के साथ घटना दिनांक में शामिल हों।
0

मेरे गरीब, PostgreSQL के साथ, आप ऐसा कर सकता है बस:

(start1, END1) overlaps (start2, end2) (start1, length1) overlaps (start2, length2)

यह अभिव्यक्ति की पैदावार सच है जब दो समयावधि (उनके अंत बिंदुओं द्वारा परिभाषित) ओवरलैप, झूठी जब वे ओवरलैप नहीं करते हैं। एंडपॉइंट्स को दिनांक, समय या समय टिकटें के जोड़े के रूप में निर्दिष्ट किया जा सकता है; या एक अंतराल के बाद एक तिथि, समय, या समय टिकट के रूप में।

चयन (दिनांक '2001-02-16', दिनांक '2001-12-21') ओवरराप्स (दिनांक '2001-10-30', दिनांक '2002-10-30'); परिणाम: सत्य चयन (दिनांक '2001-02-16', इंटरवल '100 दिन') ओवरराप्स (दिनांक '2001-10-30', दिनांक '2002-10-30'); परिणाम: झूठी

लेकिन एसक्यूएल सर्वर के तहत, मुझे नहीं पता ... खेद

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