我需要一些帮助,因为我对SQL语句不太满意......
我在数据库中有以下表格:
+------+------------+------------+
| E_ID | FromDate | ToDate |
+------+------------+------------+
| 555 | 2012-01-01 | 2012-12-31 |
| 555 | 2013-01-01 | 2013-12-31 |
| 555 | 2014-01-01 | 2014-04-30 |
| 555 | 2014-05-01 | 2014-08-15 |
| 555 | 2014-08-16 | 2014-12-31 |
| 555 | 2015-01-01 | 2015-06-25 |
| 555 | 2015-07-01 | 2015-12-31 |
+------+------------+------------+
我想合并连续的日期,按年份分组,在玩了一点后我来到这个查询:
select E_ID
,FromDate = MIN(FromDate)
,ToDate = MAX(ToDate)
from TbTest
group by E_ID
,DATEPART(YEAR,FromDate)
,DATEPART(YEAR,ToDate)
结果几乎是我想要的:
+------+------------+------------+
| E_ID | FromDate | ToDate |
+------+------------+------------+
| 555 | 2012-01-01 | 2012-12-31 |
| 555 | 2013-01-01 | 2013-12-31 |
| 555 | 2014-01-01 | 2014-12-31 |
| 555 | 2015-01-01 | 2015-12-31 |
+------+------------+------------+
这几乎是完美的。这里的问题是,在2015年的日期,我们有重叠:
| 555 | 2015-01-01 | 2015-06-25 |
| 555 | 2015-07-01 | 2015-12-31 |
因此,而不是FromDate 2015-06-26,而是2015-07-01,所以我们有6天的“差距”。对于那些特定的情况,我想拆分它们,所以我想要的结果就是:
+------+------------+-------------+
| E_ID | FromDate | ToDate |
+------+------------+-------------+
| 555 | 2012-01-01 | 2012-12-31 |
| 555 | 2013-01-01 | 2013-12-31 |
| 555 | 2014-01-01 | 2014-12-31 |
| 555 | 2015-01-01 | 2015-06-25 |
| 555 | 2015-07-01 | 2015-12-31 |
+------+------------+-------------+
简而言之,我需要连续几天才能合并,而不会缺少一天。
PS:我现在在想,ToDate有时会像9999-12-31这样,所以我的小组实际上是不正确的......感谢您的帮助!
答案 0 :(得分:1)
我很抱歉,因为我没有时间测试下面的代码,但我认为这个想法就在这里。
with aggr as
(
select E_ID,
FromDate,
ToDate,
lev = 0
from TbTest
UNION ALL
select T.E_ID,
A.FromDate,
T.ToDate,
lev = A.lev + 1
from TbTest T
inner join aggr A
on T.e_ID = A.E_ID AND datediff(day,A.Todate,T.FromDate) = 1
AND DATEPART(YEAR,A.TODate) = DATEPART(YEAR,T.FromDate)
)
select E_ID, FromDate, ToDate from aggr
EXCEPT
Select AG1.E_ID, AG1.FromDate, AG1.ToDate
from aggr AG1
inner join aggr AG2
ON AG1.E_ID = AG2.E_ID
AND AG1.Fromdate >= AG2.fromdate and AG1.todate <= AG2.todate and AG1.lev < AG2.lev
Order by E_ID, Fromdate
编辑1:我修复了脚本。这是SQL Fiddle。