Сумма и группа последовательных целых чисел - PullRequest
0 голосов
/ 21 января 2019

Мне нужно сложить и сгруппировать последовательные целые по spoken_correctly> 0.

Я могу выяснить, какие разделы являются последовательными, посмотрев на lag и lead, но затем я не уверен, как суммировать значения полей смежных групп consecutive.

Т.е., у меня есть две группы, в которых есть последовательные spoken_correctly значения> 0. Первая группа зеленого цвета имеет три ненулевых строки spoken_correctly, вторая группа зеленого цвета имеет две строки.

enter image description here

Желаемый выход:

enter image description here

Этот SQL создает первое изображение над выводом:

select *, case when (q.times_spoken_correctly > 0 and (q.lag > 0 or q.lead > 0)) then 1 else 0 end as consecutive
from (
    select *, lag(q.times_spoken_correctly) over (partition by q.profile_id order by q.profile_id) as lag, lead(q.times_spoken_correctly) over (partition by q.profile_id order by q.profile_id) as lead
    from (
        SELECT *
        FROM ( VALUES (3, 0, '2019-01-15 19:15:06'),
                      (3, 0, '2019-01-15 19:15:07'),
                      (3, 1, '2019-01-15 19:16:06'),
                      (3, 2, '2019-01-15 19:16:10'),
                      (3, 2, '2019-01-15 19:17:06'),
                      (3, 0, '2019-01-15 19:17:11'),
                      (3, 0, '2019-01-15 19:39:06'),
                      (3, 3, '2019-01-15 19:40:10'),
                      (3, 4, '2019-01-15 19:40:45')
             ) AS baz ("profile_id", "times_spoken_correctly", "w_created_at")
    ) as q
) as q

1 Ответ

0 голосов
/ 21 января 2019

Это проблема пробелов и островков, которая может быть решена путем формирования групп последовательностей с использованием row_number

select profile_id, count(*)  as consec FROM 
(
SELECT t.*, row_number() OVER ( PARTITION BY profile_id  ORDER BY w_created_at ) -
            row_number() OVER ( PARTITION BY profile_id, CASE times_spoken_correctly 
                         WHEN 0 THEN 0 ELSE 1 END 
            ORDER BY w_created_at ) as seq --group zeros and non zeros
            FROM t ORDER BY w_created_at
    ) s WHERE  times_spoken_correctly > 0 --to count only "> zero" groups.
    GROUP BY profile_id,seq;

Демо

...