Избегайте дублирования, добавляя день в BI_StartDate - PullRequest
0 голосов
/ 12 марта 2020

У меня есть следующая таблица версий сотрудников:

EmployeeId ManagerId DepartmentId StartDate   EndDate
--------------------------------------------------------
45         2         56           2017-06-27  2018-02-07
45         3         98           2018-02-07  2018-08-25
45         3         55           2018-02-25  2018-08-25
45         6         44           2018-08-25  9999-12-31

Я хочу исправить StartDate, как показано ниже, чтобы избежать дублирования, как показано ниже:

EmployeeId ManagerId DepartmentId StartDate   EndDate
---------------------------------------------------------
45         2         56           2017-06-27  2018-02-07
45         3         98           2018-02-08  2018-08-25
45         3         55           2018-02-26  2018-08-26
45         6         44           2018-08-27  9999-12-31

Лог c похож на ниже для первой записи EndDate = 2018-02-07, следующая запись будет иметь EndDate + 1 day = 2018-02-08. Для записи с EndDate = StartDate она будет иметь в обоих предыдущих EndDate + 1.

1 Ответ

2 голосов
/ 12 марта 2020

Предполагая, что ваши данные не очень плохие, вы можете использовать lag():

with toupdate as (
      select t.*,
             lag(enddate) over (partition by employee order by startdate) as prev_enddate
      from t
     ) t
update toupdate
    set startdate = dateadd(day, 1, prev_enddate)
    where startdate <> dateadd(day, 1, prev_enddate);

Если ваши данные имеют много действительно сложных перекрытий, то это немного сложнее. По сути, вы хотите сохранить даты окончания и использовать их для вычисления дат начала - для всех, кроме первой строки:

with toupdate as (
      select t.*,
             lag(enddate) over (partition by employee order by enddate) as prev_enddate,
             row_number() over (partition by employee order by startdate) as seqnum
      from t
     ) t
update toupdate
    set startdate = dateadd(day, 1, prev_enddate)
    where seqnum <> 1 and
          startdate <> dateadd(day, 1, prev_enddate);

Вам нужно seqnum (или что-то подобное), потому что вы не гарантированы что самая ранняя дата начала имеет самую раннюю дату окончания в этой ситуации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...