2013-10-08 179 views
1

如何從多個dateBegin和dateEnd獲取「最大」範圍的日期?我的問題沒有很好地解釋(因爲我不是英語),但下面的例子會告訴你我的期望。SQL:從多個開始和結束日期獲取範圍日期

我的數據庫:

enter image description here

輸出我想:

id_master beginDate endDate 
13   26/07/2014 30/08/2014 
280   28/09/2013 01/10/2013 
280   01/04/2014 11/04/2014 

說明:對於不同的id_master,我想有最小的組成日期的diferrent時期beginDate和具有產品的這些日期之間的所有天數的最大結束日期(表中的行)

當前查詢:

SELECT DISTINCT campings.id_master, CAST(campings.dateBegin AS DATETIME) AS beginDate, CAST(campings.dateEnd AS DATETIME) AS endDate 
FROM   campings 
ORDER BY id_master, beginDate, endDate 

PS:日期格式爲DD/MM/YYYY

+0

有一個類似的問題和解決方案「在開發面向SQL時,應用」電子書329頁中的http://www.cs。 arizona.edu/~rts/tdbbook.pdf –

回答

2

這可能是多了很多人爲的比它要和其他人可以拿出一個簡單的答案,但你可以試試類似如下:

WITH ordered AS (
    SELECT a.id_master, a.beginDate, a.endDate, 
     ROW_NUMBER() OVER(PARTITION BY id_master ORDER BY beginDate, endDate) AS rn 
    FROM Table1 a 
), Adjacent AS (
    SELECT a.id_master, a.beginDate, a.endDate, a.rn 
    FROM ordered a 
    UNION ALL 
    SELECT a.id_master, a.beginDate, b.endDate, b.rn 
    FROM Adjacent a 
    INNER JOIN ordered b ON a.id_master = b.id_master AND b.rn > a.rn 
     AND a.endDate >= b.beginDate 
), resolvedEnd AS (
    SELECT a.id_master, a.beginDate, MAX(a.endDate) AS endDate 
    FROM Adjacent a 
    GROUP BY a.id_master, a.beginDate 
) 
SELECT a.id_master, MIN(beginDate) AS beginDate, endDate 
FROM resolvedEnd a 
GROUP BY a.id_master, a.endDate 

SQL Fiddle example

這確實上升行號首先被安裝到每一行作出什麼保證我們遞歸只向前的方向。然後它建立一個遞歸CTE來關聯重疊行(和重疊行的重疊行)。然後解決每個開始日期的最大結束日期,然後解決每個結束日期的最早開始日期。

+0

哇!它看起來簡直太棒了!我發現它可以在小提琴上奏效,但我無法達到讓它與我的桌子一起工作,您能告訴我哪些詞我必須改變嗎?我不如你:'( –

+0

對不起,我使用'Table1'作爲表名,因爲我沒有它,你可以在第一個「有序」CTE中用你的表名替換它 –

+0

Thx,我試過了,SQL服務器企業經理們說我「AS'附近的語法不好」:'( –

-1
SELECT DISTINCT 
    id_master, 
    MIN (beginDate) OVER (PARTION BY id_master) beginDate, 
    MAX(endDate) OVER (PARTION BY id_master) endDate 
FROM campings 
0

對於其他人,這裏是我目前需要的結果。在的Informix 11.70及以上具有相同的結果這樣的結構:


SELECT id_master , MIN(beginDate) AS beginDate, endDate FROM 
    LATERAL (
    SELECT id_master, beginDate, MAX(endDate) AS endDate FROM 
     LATERAL (
     SELECT id_master, beginDate, CONNECT_BY_ROOT endDate FROM 
      LATERAL (
      SELECT id_master, beginDate, endDate, ROW_NUMBER() OVER(PARTITION BY id_master ORDER BY beginDate, endDate) AS row_num FROM campings 
     ) AS ordered 
      CONNECT BY 
      PRIOR id_master = id_master AND 
      PRIOR row_num > row_num AND 
      PRIOR endDate + 1 >= beginDate AND 
      PRIOR beginDate - 1 <= endDate 
    ) AS Adjacent 
     GROUP BY id_master, beginDate 
) AS resolvedEnd 
    GROUP BY id_master, endDate 

相關問題