Как найти перекрывающиеся временные интервалы нескольких ключевых элементов значения - PullRequest
2 голосов
/ 09 апреля 2019

Я хотел бы узнать, есть ли у меня перекрывающиеся временные интервалы, которые имеют одинаковый идентификатор и то же имя.В следующем примере записи с id = 2 и name = c перекрываются.Запись с id = 1 только для демонстрации хорошего случая.

Данная таблица:

+---+------+-------+------------+--------------+
|id | name | value | validFrom  |  validTo     |
+---+------+-------+------------+--------------+
|1  | a    | 12    | 2019-01-01 |  9999-12-31  |
|1  | b    | 34    | 2019-01-01 |  2019-10-31  |
|1  | b    | 35    | 2019-11-01 |  9999-12-31  |
|1  | c    | 13    | 2019-01-01 |  2025-12-31  |
|2  | a    | 49    | 2019-01-01 |  9999-12-31  |
|2  | b    | 99    | 2019-01-01 |  2034-12-31  |
|2  | c    | 75    | 2019-01-01 |  2019-10-31  |
|2  | c    | 84    | 2019-10-28 |  9999-12-31  |
|n  | ...  | ...   | ...        |  ...         |
+---+------+-------+------------+--------------+

Ожидаемый результат:

+---+------+
|id | name |
+---+------+
|2  | c    |
+---+------+

Спасибо за вашу помощь заранее!

1 Ответ

3 голосов
/ 09 апреля 2019

Вы можете получить перекрывающиеся строки, используя exists:

select t.*
from t
where exists (select 1
              from t t2
              where t2.id = t.id and
                    t2.name = t.name and
                    t2.value <> t.value and
                    t2.validTo > t.validFrom and
                    t2.validFrom < t.validTo
             );

Если вам нужны комбинации id / name:

select distinct t.id, t.name
from t
where exists (select 1
              from t t2
              where t2.id = t.id and
                    t2.name = t.name and
                    t2.value <> t.value and
                    t2.validTo > t.validFrom and
                    t2.validFrom < t.validTo
             );

Вы также можете сделать это с совокупным максимумом:

select t.*
from (select t.*,
             max(validTo) over (partition by id, name 
                                order by validFrom
                                rows between unbounded preceding and 1 preceding
                               ) as prev_validTo
      from t
     ) t
where prev_validTo >= validFrom;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...