对连续整数求和并分组
Sum and group consecutive integers
我需要按 spoken_correctly
> 0 对连续整数求和和分组。
我可以通过查看 lag
和 lead
找出哪些部分是连续的,但我不确定如何对连续组 consecutive
字段的值求和。
即,我有两个组,其中有连续的 spoken_correctly
值 > 0。绿色的第一组有三行非零 spoken_correctly
,绿色的第二组有两行。
期望的输出:
这 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
这是一个缺口和孤岛问题,可以通过使用 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;
我需要按 spoken_correctly
> 0 对连续整数求和和分组。
我可以通过查看 lag
和 lead
找出哪些部分是连续的,但我不确定如何对连续组 consecutive
字段的值求和。
即,我有两个组,其中有连续的 spoken_correctly
值 > 0。绿色的第一组有三行非零 spoken_correctly
,绿色的第二组有两行。
期望的输出:
这 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
这是一个缺口和孤岛问题,可以通过使用 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;