Пересекающиеся диапазоны дат суммированы - PullRequest
0 голосов
/ 29 августа 2018

Материнская компания владеет компаниями с работниками. Каждая компания может нанять и уволить сотрудника.
Сотрудник может работать в нескольких компаниях одновременно.

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

Человек может иметь много периодов работы (отпуск и возвращение). Активные работники имеют термин «9999-12-31».

Как получить результирующий набор дат найма и срока полномочий для материнской компании, игнорирующих перекрывающиеся даты?

Исходная таблица:

+--------------+----------+-------------+-------------+
| ​employee_id  | company​  | hire_date​   |  term_date​  |
+--------------+----------+-------------+-------------+
| ​1            | A​        | 2017-01-01​  | 2017-07-01​  |
| ​1            | A        | 2018-01-01​  | 2018-06-15​  |
| ​1            | B​        | 2018-04-01​  | 9999-12-31​  |
+--------------+----------+-------------+-------------+

Желаемый результат:

+--------------+-------------+-------------+
| ​employee_id  |  hire_date​  | term_date​   |
+--------------+-------------+-------------+
| ​1            | 2017-01-01​  | 2017-07-01​  |
| ​1            | 2018-01-01​  | 9999-12-31​  |
+--------------+-------------+-------------+

1 Ответ

0 голосов
/ 29 августа 2018

Начиная с SQL Server 2012, вы можете использовать LAG (подробнее здесь ) для сравнения значений между различными строками таблицы:

declare @tmp table (employee_id int, company varchar(10), hire_date date, term_date date)
insert into @tmp values
 (1,'','2017-01-01','2017-07-01')
,(1,'','2018-01-01','2018-06-15')
,(1,'','2018-04-01','9999-12-31')

 ​  ​
select employee_id, min(hire_date) as hire_date, max(term_date) as term_date
from
(
  select employee_id, hire_date, term_date, max (tmp1) over (partition by employee_id order by hire_date asc) as tmp2
  from
  (
    SELECT employee_id,
           hire_date,
           isnull (term_date, '9999-12-31') term_date,
           case
             when
               (hire_date not between lag(hire_date) over (partition by employee_id order by hire_date asc)
                   and isnull( lag(term_date) over (partition by employee_id order by hire_date asc), '9999-12-31') )
                or lag(hire_date) over (partition by employee_id order by hire_date asc) is null
                then
                  row_number() over (partition by employee_id order by hire_date asc)
             end as tmp1
    FROM @tmp
  ) x
) y
group by employee_id, tmp2

Результаты:

enter image description here

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