2013-10-08 125 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 

相关问题