按值对行进行分组,直到它更改(分组包括第一个更改的值)
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 中特定列中的模式更改对行进行分组