Найти "прерывание" в датах с SQL

У меня есть таблица с полями: VALID_FROM - VALID_UP - CLIENT

Допустим

 2005 - 2006 - Smith
 2006 - 2009 - Smith
 2010 - 2013 - Smith
 2013 - 2014 - Smith
 2015 - 2016 - Smith
 2016 - 2017 - Smith
 2017 - today - Smith
 2014 - today - Bob 

То, что я хочу найти, это дата начала после перерыва. В этом случае:

2015 - 2016 - Smith
2014 - today - Bob

Там могут быть сотни записей - мне всегда нужно ПЕРВОЕ прерывание, начиная с сегодняшнего дня.

Есть ли шанс, что я могу сделать это в (Oracle) SQL?

1 ответ

Решение

Одним из подходов здесь является использование LAG() аналитическая функция для проверки каждой строки на прерванную дату, для каждого клиента. Затем выполните подзапрос, чтобы ограничиться только последним прерыванием. Было бы трудно объяснить запрос ниже словами, но если вы выполняете каждый фрагмент, начиная с самого внутреннего подзапроса и наращивая его, это должно иметь смысл для вас.

SELECT
    t.VALID_FROM,
    t.VALID_UP,
    t.CLIENT
FROM
(
    SELECT t.*,
        ROW_NUMBER() OVER (PARTITION BY CLIENT ORDER BY VALID_FROM DESC) rn
    FROM
    (
        SELECT t.*,
            LAG(VALID_UP) OVER (PARTITION BY CLIENT ORDER BY VALID_FROM) v_lag
        FROM yourTable t
    ) t
    WHERE t.VALID_FROM <> COALESCE(t.v_lag, -1)
) t
WHERE t.rn = 1;

Выход:

Кажется, я никогда не смог заставить Rextester работать на Oracle, но мне удалось получить демо, работающее на SQL Server:

демонстрация

Другие вопросы по тегам