我有一个表格和下面的最小样本行。我想以更聪明的方式获得预期的结果。有人有什么好主意吗?
create table foo (
id int,
s datetime,
e datetime,
value float
);
insert foo values
(1, '2019-1-1 1:00:00', '2019-1-1 3:00:00', 10.0),
(1, '2019-1-1 1:30:00', '2019-1-1 3:00:00', 10.0),
(1, '2019-1-1 4:00:00', '2019-1-1 5:00:00', 10.0),
(1, '2019-1-1 4:30:00', '2019-1-1 6:00:00', 10.0),
(2, '2019-1-1 2:00:00', '2019-1-1 6:00:00', 15.0),
(2, '2019-1-1 2:00:00', '2019-1-1 6:00:00', 10.0);
我想要这样的结果。
1, '2019-1-1 1:00:00', '2019-1-1 3:00:00', 10.0
1, '2019-1-1 4:00:00', '2019-1-1 6:00:00', 10.0
2, '2019-1-1 2:00:00', '2019-1-1 6:00:00', 15.0
与周期重叠的行相比,它们的周期更长,s和e合并的周期将更长,并且值更大。
其他信息
我认为“智能方式”更易于理解(例如,较少的子查询可能更好),并且执行速度更快。
实际上,我在示例代码中的“ foo”表中有一个附加的地理Point列,并且必须从同一时间段组中具有最低“值”的行中选择一个Point。我曾经想过我的逻辑。没有许多子查询或游标,我不知道要获得结果。因此,我想让我的问题更简单,以便对此案有所了解。
答案 0 :(得分:2)
这是一种空白和岛屿问题。您可以通过确定重叠时间段的开始时间(即某个时间段与之前的任何时间段都不重叠的时间)来解决该问题。
然后,起点的累积总和定义一个组。您可以按组进行汇总:
select id, min(s) as s, max(e) as e, max(value)
from (select f.*,
sum(case when max_e < s then 1 else 0 end) over (partition by id order by s) as grp
from (select f.*,
max(e) over (partition by id order by s rows between unbounded preceding and 1 preceding) as max_e
from foo f
) f
) f
group by id, grp;
Here是db <>小提琴。
答案 1 :(得分:-1)
使用max()聚合函数
select id,s,e,max(value) from table
group by id,s,e