按值分组行直到它改变(分组包括第一个改变的值)

Grouping rows by value until it changes (grouping includes the first changed value)

我有以下数据集:

行按 start_time 字段升序排序,我想对具有一系列假值的行进行分组,直到第一个真值,包括第一个真值值.

也就是说,对于上面的数据集,我想要以下输出:

(分组字段可以包括我写的以外的值)

我认为 window 总和可以做你想做的事:

select t.*, 
    1 + coalesce(sum(case when bool = true then 1 else 0 end) over(
            order by start_time
            rows between unbounded preceding and 1 preceding
        ), 0) as grp
from mytable t

使用 Vertica,您可以使用 Vertica 可爱的 CONDITIONAL_TRUE_EVENT() 函数编写可读性更好的查询,该函数是一个分析函数,在每个 PARTITION BY 表达式处以 0 开头,每次递增 1布尔表达式为真。

每次间隔超过 1 天或前一行与当前行在 TRUE 时,您都需要增加。所以:

WITH
-- your input ...
indata(start_time,bool) AS (
           SELECT TIMESTAMP '2020-10-12 08:00',FALSE
 UNION ALL SELECT TIMESTAMP '2020-10-12 08:04',FALSE
 UNION ALL SELECT TIMESTAMP '2020-10-12 08:08',TRUE
 UNION ALL SELECT TIMESTAMP '2020-10-12 08:18',TRUE
 UNION ALL SELECT TIMESTAMP '2020-12-10 08:30',FALSE
 UNION ALL SELECT TIMESTAMP '2020-12-10 08:31',FALSE
 UNION ALL SELECT TIMESTAMP '2020-12-10 08:34',FALSE
 UNION ALL SELECT TIMESTAMP '2020-12-10 08:38',FALSE
)
SELECT
  *
, CONDITIONAL_TRUE_EVENT(
      start_time - LAG(start_time) > INTERVAL '1 DAY'
   OR (bool AND LAG(bool) )
  ) OVER(
    PARTITION BY 1 ORDER BY start_time
  ) + 1
  AS sessid
FROM indata;
-- out start_time         |bool |sessid
-- out 2020-10-12 08:00:00|false|     1
-- out 2020-10-12 08:04:00|false|     1
-- out 2020-10-12 08:08:00|true |     1
-- out 2020-10-12 08:18:00|true |     2
-- out 2020-12-10 08:30:00|false|     3
-- out 2020-12-10 08:31:00|false|     3
-- out 2020-12-10 08:34:00|false|     3
-- out 2020-12-10 08:38:00|false|     3