Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Postgresql合并连续行_Sql_Postgresql - Fatal编程技术网

使用Postgresql合并连续行

使用Postgresql合并连续行,sql,postgresql,Sql,Postgresql,我有一张这样的老虎机桌: Column | Type | ------------+-----------------------------+ id | integer | begin_at | timestamp without time zone | end_at | timestamp without time zone | user_id | int

我有一张这样的老虎机桌:

   Column   |            Type             |
------------+-----------------------------+
 id         | integer                     |
 begin_at   | timestamp without time zone |
 end_at     | timestamp without time zone |
 user_id    | integer                     |
我喜欢选择连续时间的合并行。假设我有简化的数据,如:

(1, 5:15, 5:30, 1)
(2, 5:15, 5:30, 2)
(3, 5:30, 5:45, 2)
(4, 5:45, 6:00, 2)
(5, 8:15, 8:30, 2)
(6, 8:30, 8:45, 2)
我想知道是否可以选择格式如下的行:

(5:15, 5:30, 1)
(5:15, 6:00, 2) // <======= rows id 2,3 and 4 merged
(8:15, 8:45, 2) // <======= rows id 5 and 6 merged
编辑: 这是我的建议

我正在使用Postgresql,9.3版


谢谢大家!

这里有一种解决这个问题的方法。创建一个标志,确定一条记录是否与上一条记录重叠。这是一个小组的开始。然后取此标志的累计和,并将其用于分组:

select user_id, min(begin_at) as begin_at, max(end_at) as end_at
from (select s.*, sum(startflag) over (partition by user_id order by begin_at) as grp
      from (select s.*,
                   (case when lag(end_at) over (partition by user_id order by begin_at) >= begin_at
                         then 0 else 1
                    end) as startflag
            from slots s
           ) s
     ) s
group by user_id, grp;

是个SQL高手。

戈登·林诺夫已经提供了我投赞成票的答案

我也用过同样的方法,但我想处理这个问题。 于是我想到:

选择minid b_id、minbegin_at b_at、maxend_at e_at、grp、user_id 从…起 选择t.*,按id grp对订单进行汇总 从…起 选择s.*,而不是r-|-lagr,1,r 按用户划分的分区\u id按id排序::int g 从选择id、开始位置、结束位置、用户id、, Tsrange从插槽s开始,在插槽s结束 T U 按grp分组,用户\u id grp订购; 不幸的是,在顶层必须使用minbegin_at和maxend_at,因为基于范围的联合运算符+没有聚合函数


我创建了具有独占上限的范围,这允许我使用。我将当前tsrange与前一行上的tsrange进行比较,如果没有上一行,则默认为当前tsrange。然后我取消比较并强制转换为整数,在新组启动时,这会给我1。

您能SQLFIDLE数据吗?SQL Ser的类似问题使用递归查询时,从前面不可连接的起始存根开始。通过连接下面的段进行扩展。最终只选择最长的路径。