按值对行进行分组,直到它更改(分组包括第一个更改的值)

Posted

技术标签:

【中文标题】按值对行进行分组,直到它更改(分组包括第一个更改的值)【英文标题】:Grouping rows by value until it changes (grouping includes the first changed value) 【发布时间】:2020-10-13 07:48:48 【问题描述】:

我有以下数据集:

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

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

(分组字段可以包含我写的以外的其他值)

【问题讨论】:

【参考方案1】:

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

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

【讨论】:

【参考方案2】:

使用 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

【讨论】:

以上是关于按值对行进行分组,直到它更改(分组包括第一个更改的值)的主要内容,如果未能解决你的问题,请参考以下文章

根据 SQL Server 2008 R2 中特定列中的模式更改对行进行分组

Postgres 按值更改分区/分组

使用 ag 网格,尝试按一个值对行分组并显示另一个

根据从下一行开始的当前值对行进行分组

如何在reactjs / javascript中按值对对象数组进行分组

如何使用 Python 在一个时间段内对行进行分组