Как найти конечную точку того же значения с интервалом? - PullRequest
0 голосов
/ 19 декабря 2018

У меня есть такая таблица ниже.

ID        Time         State 
1          1         "active"
1          2         "active"
1          3         "active"
1          4        "inactive"
2          2        "inactive"
2          3         "active"
3          1         "active"
3          3         "active"
3          4        "inactive"   

Я хочу отсортировать таблицу по времени начала / окончания по состоянию.
Может потребоваться lag() оконная функция, но я не знаюкак найти конечную точку того же состояния.

Моя ожидаемая таблица должна выглядеть следующим образом.

ID        Start          End           State 
1          1              4           "active"
1          4             NULL        "inactive"
2          2              3          "inactive"
2          3             NULL         "active"
3          1              4           "active"
3          4             NULL        "inactive"  

1 Ответ

0 голосов
/ 19 декабря 2018

demo: db <> fiddle

SELECT DISTINCT ON (sum)  -- 5
    id,
    -- 4
    first_value(time) OVER (PARTITION BY sum ORDER BY time) as start,
    first_value(lead) OVER (PARTITION BY sum ORDER BY time DESC) as end,
    state
FROM (
    SELECT
        *, 
        -- 3
        SUM(CASE WHEN is_prev_state THEN 0 ELSE 1 END) OVER (ORDER BY id, time)
    FROM (
        SELECT 
            *, 
            -- 1
            lead(time) OVER (PARTITION BY id ORDER BY time),
            -- 2                
            state = lag(state) OVER (PARTITION BY id ORDER BY time) as is_prev_state
        FROM states
    )s
)s
  1. lead() принимает следующее значение в текущей строке.Например, time == 4 (id == 1) переходит в строку с time == 3.Идея состоит в том, чтобы получить возможный конец группы в правом ряду.
  2. lag() делает противоположную вещь.Принимает предыдущее значение текущей строки.С помощью этого я могу проверить, изменилось ли состояние: текущее состояние совпадает с последним.
  3. С помощью этой строки я создаю группы для каждого отдельного состояния: если изменение состояния произошло, суммируйте одно значение,Если не удерживать одно и то же значение (добавление 0).
  4. Теперь у меня есть возможное последнее значение для каждого состояния (данное через (1)) и я могу получить первое значение.Это делается с помощью оконной функции first_value(), которая дает вам первое значение упорядоченной группы.Чтобы получить последнее значение, нужно просто заказать группу по убыванию.( Почему бы не использовать last_value())
  5. DISTINCT ON фильтрует только самую первую строку (сгенерированной функцией SUM())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...