基于一列对连续行进行分组

Posted

技术标签:

【中文标题】基于一列对连续行进行分组【英文标题】:Group consecutive rows based on one column 【发布时间】:2019-04-12 14:42:20 【问题描述】:

假设我从select * from journeys 的结果中得到这张表:

timestamp     | inJourney (1 = true and 0 = false)
--------------------------------------------------
time1         | 1
time2         | 1
time3         | 1
time4         | 0
time5         | 0
time6         | 1
time7         | 1
time8         | 1

预期:

timestamp     | inJourney (1 = true and 0 = false)
--------------------------------------------------
time1         | 1
time4         | 0
time8         | 1

注意:时间戳并不重要,因为我只想计算行程次数。

知道我要做什么吗?

【问题讨论】:

和这个一样:***.com/a/30880137/939860。或者这个:dba.stackexchange.com/q/112846/3684 @ErwinBrandstetter 你是对的。我没找到那个帖子。谢谢。 一旦您知道搜索词“间隙和岛屿”,它就会变得更容易。但问题仍然有很多变种。 【参考方案1】:

这是一个孤岛问题。使用row_number()的区别:

select injourney, min(timestamp), max(timestamp)
from (select t.*,
             row_number() over (order by timestamp) as seqnum,
             row_number() over (partition by injourney, order by timestamp) as seqnum_i
      from t
     ) t
group by injourney, (seqnum - seqnum_i)
order by min(timestamp);

【讨论】:

非常感谢。我不知道这个问题(缝隙和岛屿问题),但现在我知道了。我已经在这几个小时了。你值得拥有一个美妙的周末。 @GordonLinoff【参考方案2】:

这是一个gaps-and-islands问题,你可以尝试使用ROW_NUMBER窗口函数从结果集中获取间隙然后使用MIN

你可以试试这个。

查询 #1

SELECT MIN(timestamp),inJourney 
FROM (
SELECT *,
    ROW_NUMBER() OVER(ORDER BY timestamp)  - ROW_NUMBER() OVER(PARTITION BY inJourney ORDER BY timestamp) grp
  FROM journeys
) t1
GROUP BY grp,inJourney 
ORDER BY MIN(timestamp);

| min   | injourney |
| ----- | --------- |
| time1 | 1         |
| time4 | 0         |
| time6 | 1         |

View on DB Fiddle

【讨论】:

以上是关于基于一列对连续行进行分组的主要内容,如果未能解决你的问题,请参考以下文章

按数组中的指定列对行进行分组

按 ID 和更新列对 SQL 中的行进行分组

SQL:按选定列对记录进行分组

使用 Scala 根据 RDD 中的多个键列对值进行分组的最快方法是啥? [复制]

(pySpark 中分组数据的模式

按列对分组数据帧进行采样