我正在尝试将我从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;
答案 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;