DB2 SQL配对日期

时间:2015-04-08 15:32:58

标签: sql date db2

我正在尝试将我从SQL中获取的日期配对。目前的输出看起来像这样:

 start_date   end_date 
 2015-02-02  2015-02-02  
 2015-02-02  2015-02-03    
 2015-02-03  2015-02-03  
 2015-04-12  2015-02-12

我希望将输出配对,以便选择日期组的最小和最大日期,以便输出看起来像这样:

 start_date   end_date 
 2015-02-02  2015-02-03    
 2015-04-12  2015-02-12

使用第一个响应我得到这样的东西,我相信我已经格式化了这个错误,我得到了与以前相同的日期对,但它确实运行了。

select min(date), max(date)
from (select date,
         sum(case when sum(inc) = 0 then 1 else 0 end) over (order by   date desc) as grp
  from (select t1.datev as date, 1 as inc
        from  table2 t1, 
              table3 c, 
              table4 cr

where t1.datev between date(c.e_start_date) and date(c.e_end_date)
and   t1.datev not in (select date(temp.datev) from mdmins11.temp temp where temp.number < 4000 and temp.organisation_id = 11111)
and   c.tp_cd in (1,6)
and   cr.from_id = c.id
and   cr.organisation_id = 11111

        union all
        select t.datev as date, -1 as inc
        from  table1 t,
              table3 c, 
              table4 cr

where t.datev between date(c.e_start_date) and date(c.e_end_date)
and   t.datev not in (select date(temp.datev) from mdmins11.temp temp where temp.number < 4000 and temp.organisation_id = 11111)
and   c.tp_cd in (1,6)
and   cr.from_id = c.id
and   cr.organisation_id = 11111
       ) t
  group by date
 ) t
group by grp;

1 个答案:

答案 0 :(得分:0)

一种方法是确定非重叠日期组的开始位置。为此,您可以使用not exists。然后在所有记录上计算此标志。这使用窗口函数。但是,这会产生问题,因为您在同一天有多次启动。

另一种方法是跟踪开始和停止并记录总和为零的位置。这些代表组之间的界限。以下内容适用于您的数据:

select min(date), max(date)
from (select date,
             sum(case when sum(inc) = 0 then 1 else 0 end) over (order by date desc) as grp
      from (select start_date as date, 1 as inc
            from table
            union all
            select end_date as date, -1 as inc
            from table
           ) t
      group by date
     ) t
group by grp;

如果在给定日期允许重复值,则此类问题会变得更加复杂。仅给出日期,这是具有挑战性的。每行都有一个单独的唯一ID,那么就有更强大的解决方案。

编辑:

更强大的解决方案:

select min(start_date), max(end_date)
from (select t.*, sum(StartGroupFlag) over (order by start_date) as grp
      from (select t.*,
                   (case when not exists (select 1
                                          from table t2
                                          where t2.start_date < t.start_date and
                                                t2.end_date >= t.start_date
                                         )
                         then 1 else 0
                    end) as StartGroupFlag
            from table t
           ) t
      ) t
group by grp;