Sql 试试看!另外,我有一种感觉,你可以通过计算循环中的可传递边来优化它,使其在O(logN)中运行,并避免启动时的mins/maxs操作,但不能100%确定它会起作用!我花了一段时间摸索,但我的钦佩之情一直在增长。非常优雅!谢谢。看起来可能有用-你在我向naj
Sql 试试看!另外,我有一种感觉,你可以通过计算循环中的可传递边来优化它,使其在O(logN)中运行,并避免启动时的mins/maxs操作,但不能100%确定它会起作用!我花了一段时间摸索,但我的钦佩之情一直在增长。非常优雅!谢谢。看起来可能有用-你在我向naj,sql,oracle,analytics,Sql,Oracle,Analytics,试试看!另外,我有一种感觉,你可以通过计算循环中的可传递边来优化它,使其在O(logN)中运行,并避免启动时的mins/maxs操作,但不能100%确定它会起作用!我花了一段时间摸索,但我的钦佩之情一直在增长。非常优雅!谢谢。看起来可能有用-你在我向najmeddine建议的数据集上测试过吗?(他的测试集+1行)over()是做什么的?(我是Sybase人,不是Oracle:()如果有人能写出与Sybase语法相同的东西,我会非常棒(我当然希望这不会用到)。@DVK:我按照您的建议对数据集进行了
试试看!另外,我有一种感觉,你可以通过计算循环中的可传递边来优化它,使其在O(logN)中运行,并避免启动时的mins/maxs操作,但不能100%确定它会起作用!我花了一段时间摸索,但我的钦佩之情一直在增长。非常优雅!谢谢。看起来可能有用-你在我向najmeddine建议的数据集上测试过吗?(他的测试集+1行)over()是做什么的?(我是Sybase人,不是Oracle:()如果有人能写出与Sybase语法相同的东西,我会非常棒(我当然希望这不会用到)。@DVK:我按照您的建议对数据集进行了查询测试,并且附加的行正确地合并到最后一段中。OVER关键字将组函数转换为窗口函数(该功能应用于OVER关键字后定义的窗口)。分析功能非常强大,唉,我不是Sybase人,我不知道是否可以在Sybase中编写等价的东西:>
machineid partid start_time end_time
--------- ------ ---------------- ----------------
1 2 2009-10-05 09:00 NULL
1 3 2009-10-05 08:00 2009-10-05 10:00
2 2 2009-09-30 12:00 2009-09-30 14:00
3 4 2009-09-28 13:00 2009-09-28 15:00
3 2 2009-09-28 12:00 2009-09-28 14:00
machineid start_time end_time
--------- ---------------- ----------------
1 2009-10-05 08:00 NULL
2 2009-09-30 12:00 2009-09-30 14:00
3 2009-09-28 12:00 2009-09-28 15:00
SELECT machineid, min(start_time), max(ifnull(end_time, '3000-01-01 00:00'))
FROM faults
GROUP BY machineid
select a.machineid, a.start_time, a.end_time, b.start_time, b.end_time
from faults a,
faults b,
where a.machineid = b.machineid
and b.start_time >= a.start_time
and b.start_time <= a.end_time;
SELECT DISTINCT
t1.machineId,
MIN(t2.start_time) start_time,
MAX(COALESCE(t2.end_time, '3210/01/01')) end_time
FROM FAULTS t1
JOIN FAULTS t2 ON t1.machineId = t2.machineId
AND ((t2.start_time >= t1.start_time
AND (t1.end_time IS NULL OR t2.start_time <= t1.end_time)
)
OR
(t1.start_time >= t2.start_time
AND (t2.end_time IS NULL OR t1.start_time <= t2.end_time)
))
GROUP BY t1.machineId, t1.part_id
machine_id |part_id |start_time |end_time
-------------------------------------------------------------------------
1 |2 |05 Oct 2009 09:00:00 |NULL
1 |3 |05 Oct 2009 08:00:00 |05 Oct 2009 10:00:00
2 |2 |30 Sep 2009 12:00:00 |30 Sep 2009 14:00:00
2 |3 |30 Sep 2009 15:00:00 |30 Sep 2009 16:00:00
2 |4 |30 Sep 2009 16:00:00 |30 Sep 2009 17:00:00
3 |2 |28 Sep 2009 12:00:00 |28 Sep 2009 14:00:00
3 |4 |28 Sep 2009 13:00:00 |28 Sep 2009 15:00:00
machine_id |start_time |end_time
-----------------------------------------------------------------
1 |05 Oct 2009 08:00:00 |01 Jan 3210 00:00:00
2 |30 Sep 2009 12:00:00 |30 Sep 2009 14:00:00
2 |30 Sep 2009 15:00:00 |30 Sep 2009 17:00:00
3 |28 Sep 2009 12:00:00 |28 Sep 2009 15:00:00
select min(p1.start_time), max(p2.end_time), p1.partition,p2.partition
from partitions p1, partitions p2
where p1.partition = p2.partition
group by p1.partition,p2.partition
/* This will need to be tweaked using COALESCE
to deal with NULL end times in obvious way) */
|----------|
|---------------|
|----------------|
SELECT machineid, MIN(start_time), MAX(end_time)
FROM (SELECT machineid, start_time, end_time,
SUM(gap) over(PARTITION BY machineid
ORDER BY start_time) contiguous_faults
FROM (SELECT machineid, start_time,
coalesce(end_time, DATE '9999-12-31') end_time,
CASE
WHEN start_time > MAX(coalesce(end_time,
DATE '9999-12-31'))
over(PARTITION BY machineid
ORDER BY start_time
ROWS BETWEEN UNBOUNDED PRECEDING
AND 1 preceding)
THEN 1
END gap
FROM faults))
GROUP BY machineid, contiguous_faults
ORDER BY 1, 2