2009-06-22 127 views
6

我有下面的一組日期(DD/MM/YYYY)匹配我的數據庫事件之間:計算丟失的日期範圍和重疊的日期範圍兩個日期

 
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 

事件有開始和結束日期(次數無關緊要),並且NULL endDate意味着事件仍在進行中。

我想確定的是兩個任意日期之間的日期範圍,其中a)沒有事件和b)事件重疊。

所以對於01/04/2009的輸入日期範圍 - 30/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 

注意,在兩個相鄰的重疊範圍將是可接受的,因爲一個結果。

任何人都可以請幫我用SQL算法來生成這個結果集?

編輯:目標平臺數據庫是SQL Server 2005.日期記錄爲10/05/2009 00:00:00,這意味着該事件在10/5/2009 00:00:00之間結束了一段時間, 10/5/2009 23:59:59。開始日期也是如此。輸入日期範圍因此也可以理解爲01/04/2009 00:00:00 - 30/06/2009 23:59:59。

+1

哪個數據庫平臺(S)將您運行此查詢? – 2009-06-22 07:04:44

回答

4

它的功能有點變化趨於平緩相交的時間跨度在SQL Server

這是罕見的情形之一時,光標爲基礎的方法在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

Quassnoi的答覆是否解決了該問題?如果是的話,函數中數據表的名稱是什麼。 – 2009-09-08 06:36:43

1

沒有真正理解你想解決什麼問題,這是我的解決方案一些問題,從我的頭頂:

  1. 創建表函數(UDF)「全日」,將返回一年中的所有日期。
  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,你能做到這一點簡單地說:

(啓動1,END1)重疊(START2,END2) (啓動1,長度1)重疊(START2,長度2)

這表達產量當兩個時間段(由其端點定義)重疊時爲true,當它們不重疊時爲false。可以將端點指定爲日期,時間或時間戳對;或作爲日期,時間或時間戳後跟一個時間間隔。 SELECT(DATE'2001-02-16',DATE'2001-12-21')OVERLAPS (DATE'2001-10-30',DATE'2002-10-30'); 結果:true SELECT(DATE'2001-02-16',INTERVAL'100 days')OVERLAPS (DATE'2001-10-30',DATE'2002-10-30'); 結果:假

但在SQL Server中,我不知道...對不起