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