Как совместить даты начала и окончания без перерывов во времени? - PullRequest
0 голосов
/ 04 мая 2018

Я пробовал много способов, но безуспешно, чтобы объединить даты начала и даты окончания, где идентификатор записи одинаков, и объединить, где нет перерыва в дате

CREATE TABLE #t (
    A_ID VARCHAR(100),
    BDate VARCHAR(100),
    CDate VARCHAR(100)
)

INSERT INTO #T
  (A_ID, BDate, CDate)
VALUES
('1000','2017/12/01','2017/12/31'),
('1000','2018/01/01','2018/03/31'),
('1000','2018/05/01','2018/05/31')
Select A_ID, bDate,cDate from 
   (
   select BDate,A_ID,Cdate,lead(Bdate) over (order by Bdate) next_BDate from #T as t2
   where   exists ( select null from #T as t1
                       where t1.A_ID = t2.A_ID and t1.Bdate <= t2.Bdate and t1.CDate <=t2.CDate )
   ) as combine

  where bDate < Cdate
    order by BDate;

Хотелось бы увидеть:

1000 2017/12/01 2018/03/31 (no break in first two dates) 
1000 2018/05/01 2018/05/31 (Break between 4-1-18 and 5-1-18)

Ответы [ 2 ]

0 голосов
/ 04 мая 2018

Как это работает для вас?

declare @table table (a_id int, bdate date, cdate date, id int)
    insert @table
    select a_id, bdate, cdate, 
    case when lag(cdate, 1,cdate) over(partition by a_id order by bdate)  in (cdate, dateadd(day, -1, bdate))
    then 1 else 2 end id from #t 


    select a.a_id, min(a.bdate)bdate, max(a.cdate)cdate from @table a
    left join 
    @table b
    on a.id=b.id and a.a_id=b.a_id and b.id=1
    group by a.a_id, a.id
0 голосов
/ 04 мая 2018

Это проблема пробелов и островков , в зависимости от ваших реальных данных решение, основанное на лучших OLAP-функциях, может быть более эффективным, чем рекурсия:

with combine as
 (
   select BDate,A_ID,Cdate,
      -- find the gap and flag it
      case when lag(Cdate)
                over (partition by A_ID
                      order by CDate) = dateadd(day,-1, BDate)
           then 0
           else 1
      end as flag
   from T
 )
, groups as
 (
   Select A_ID, bDate,cDate,
      -- cumulative sum over 0/1 to assign the same group number for row without gaps
      sum(flag)
      over (partition by A_ID
            order by Bdate) as grp
   from combine
 )
-- group consecutive rows into one
select A_ID, min(BDate), max(CDate)
from groups
group by A_ID, grp
order by min(BDate);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...