SQL: FIlter строк по направлению - PullRequest
0 голосов
/ 05 ноября 2018

У меня есть таблица с двумя столбцами: дата (отметка времени), статус (логическое значение). У меня много ценности, как:

| date                      | status    |
|-------------------------- |--------   |
| 2018-11-05T19:04:21.125Z  | true      |
| 2018-11-05T19:04:22.125Z  | true      |
| 2018-11-05T19:04:23.125Z  | true      |
....

Мне нужно получить такой результат:

| date_from                 | date_to                   | status    |
|-------------------------- |-------------------------- |--------   |
| 2018-11-05T19:04:21.125Z  | 2018-11-05T19:04:27.125Z  | true      |
| 2018-11-05T19:04:27.125Z  | 2018-11-05T19:04:47.125Z  | false     |
| 2018-11-05T19:04:47.125Z  | 2018-11-05T19:04:57.125Z  | true      |

Итак, мне нужно отфильтровать все «одинаковые» значения и получить взамен только период состояния true / false.

Я создаю запрос следующим образом:

SELECT max("current_date"), current_status, previous_status
FROM (SELECT date as "current_date",
             status as current_status,
             (lag(status, 1) OVER (ORDER BY msgtime))::boolean AS previous_status
      FROM "table" as table
      ) as raw_data
group by current_status, previous_status

но в ответ я получаю только не более 4 значения

Ответы [ 2 ]

0 голосов
/ 05 ноября 2018

Это проблема пробелов и островков. Типичный метод использует разницу номеров строк:

select min(date), max(date), status
from (select t.*,
             row_number() over (order by date) as seqnum,
             row_number() over (partition by status order by date) as seqnum_s
      from t
     ) t
group by status, (seqnum - seqnum_s);
0 голосов
/ 05 ноября 2018

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

WITH cte1 AS (
    SELECT date, status, CASE WHEN LAG(status) OVER (ORDER BY date) = status THEN 0 ELSE 1 END AS chg
    FROM yourdata
), cte2 AS (
    SELECT date, status, SUM(chg) OVER (ORDER BY date) AS grp
    FROM cte1
)
SELECT MIN(date) AS date_from, MAX(date) AS date_to, status
FROM cte2
GROUP BY grp, status
ORDER BY date_from

DB Fiddle

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