Хитрый запрос для postgres. Представьте себе, у меня есть набор строк с логическим столбцом, который называется (например) успех. Как это:
id | success
9 | false
8 | false
7 | true
6 | true
5 | true
4 | false
3 | false
2 | true
1 | false
И мне нужно рассчитать длину последней (не) удачной серии. Например в этом случае это будет «3» для успешного и «2» для не успешного. Или используя оконные функции, затем что-то вроде:
id | success | length
9 | false | 2
8 | false | 2
7 | true | 3
6 | true | 3
5 | true | 3
4 | false | 1
3 | true | 2
2 | true | 2
1 | false | 1
(обратите внимание, что мне, как правило, нужна длина только последних серий, а не всех)
Самый близкий ответ, который я нашел, был этой статьей:
https://jaxenter.com/10-sql-tricks-that-you-didnt-think-were-possible-125934.html
(См. № 5)
Однако postgres не поддерживает опцию «IGNORE NULLS», поэтому запрос не работает. Без «IGNORE NULLS» он просто возвращает мне нули в столбце длины.
Вот самое близкое, что мне удалось получить:
WITH
trx1(id, success, rn) AS (
SELECT id, success, row_number() OVER (ORDER BY id desc)
FROM results
),
trx2(id, success, rn, lo, hi) AS (
SELECT trx1.*,
CASE WHEN coalesce(lag(success) OVER (ORDER BY id DESC), FALSE) != success THEN rn END,
CASE WHEN coalesce(lead(success) OVER (ORDER BY id DESC), FALSE) != success THEN rn END
FROM trx1
)
SELECT trx2.*, 1
- last_value (lo) IGNORE nulls OVER (ORDER BY id DESC ROWS BETWEEN
UNBOUNDED PRECEDING AND CURRENT ROW)
+ first_value(hi) OVER (ORDER BY id DESC ROWS BETWEEN CURRENT ROW
AND UNBOUNDED FOLLOWING)
AS length FROM trx2;
Есть ли у вас идеи такого запроса?