【发布时间】:2017-06-15 23:20:45
【问题描述】:
我想为每个id 获取连续的enter_day 和leave_day 值的第一个enter_date 和最后一个leave_date。鉴于此示例数据:
+-----+------------+------------+-----------+-----------+
| id | enter_date | leave_date | enter_day | leave_day |
+-----+------------+------------+-----------+-----------+
| 111 | 2016-07-29 | 2016-12-01 | 1 | 75 |
| 111 | 2016-12-02 | 2017-01-13 | 76 | 95 |
| 111 | 2017-01-17 | 2017-06-02 | 96 | 181 |
| 222 | 2016-07-29 | 2016-12-02 | 1 | 76 |
| 222 | 2017-01-30 | 2017-06-02 | 105 | 181 |
| 333 | 2016-08-01 | 2017-06-02 | 1 | 180 |
+-----+------------+------------+-----------+-----------+
我想要以下结果:
+-----+------------+------------+
| id | enter_date | leave_date |
+-----+------------+------------+
| 111 | 2016-07-29 | 2017-06-02 |
| 222 | 2016-07-29 | 2016-12-02 |
| 222 | 2017-01-30 | 2017-06-02 |
| 333 | 2016-08-01 | 2017-06-02 |
+-----+------------+------------+
我想要一条 ID 为 111 的记录,因为任何 enter_day 和之前的 leave_day 之间没有间隔。
我想要 ID 222 的两条记录,因为存在间隔(第 75 天到第 104 天)。
编辑:到目前为止,我没有为 ID 111 提供正确的leave_date:
with cte as (
select a.id, a.enter_date, a.leave_date, b.enter_date next_ed, b.leave_date next_ld
from #tbl a
join #tbl b on b.id = a.id and b.enter_day = a.leave_day + 1
)
select id, min(enter_date) enter_date, max(leave_date) leave_date
from cte
group by id
union
select a.id, a.enter_date, a.leave_date
from #tbl a
left join #tbl b on b.id = a.id and b.enter_day = a.leave_day + 1
left join cte c on c.id = a.id and c.next_ed = a.enter_date and c.next_ld = a.leave_date
where b.id is null and c.id is null
order by 1,3
【问题讨论】:
-
到目前为止您尝试过什么?这不是代码编写服务。
-
搜索间隙和孤岛。这是此类查询的经典示例。
-
我整个上午都在查看 gaps-and-islands 示例,我发现的所有示例都是针对单个列中的间隙或日期中的间隙(我不想要的) .
标签: sql sql-server sql-server-2008 gaps-and-islands