ORACLE SQL基于不同的基于时间的事件连接表

时间:2014-10-10 06:40:03

标签: sql oracle

我有两张桌子:

  • PROCESSOR_EVENT(ID,时间,机器,名称,州)
  • COMM_EVENT(ID,时间,机器,名称,类型)

我想在下一个PROCESSOR_EVENT.Time之前检索PROCESSOR_EVENT.Time和下一个COMM_EVENT之间的区别。

即。在下一个PROCESSOR_EVENT之前发生的PROCESSOR_EVENT之后的第一个COMM_EVENT事件。

示例数据:

PROCESSOR_EVENT(Id, Time, Machine, Name, State)
1, 01:00:00, TRX4, Ignition, Heated
2, 01:00:03, TRX1, Movement, Triangulating
3, 01:00:23, TRX4, Movement, Heated
4, 01:00:32, TRX4, Direction Change, Stable
5, 01:00:56, TRX4, Stopping, Heated

COMM_EVENT(Id, Time, Machine, Name, Type)
1, 01:00:02, TRX4, Direction request, Request
2, 01:00:15, TRX4, Direction acknowledgement, Acknowledgement
3, 01:00:16, TRX1, Position change, Command
4, 01:00:34, TRX4, Direction request, Request
5, 01:01:02, TRX4, Position change, Command

预期回报:

PROCESSOR_EVENT.Time, PROCESSOR_EVENT.Machine, PROCESSOR_EVENT.Name, COMM_EVENT.Time, COMM_EVENT.Type, TimeDifference
01:00:00, TRX4, Ignition, 01:00:02, Request, 2
01:00:03, TRX1, Movement, 01:00:16, Command, 13
01:00:23, TRX4, Movement, null, null, null
01:00:32, TRX4, Direction Change, 01:00:34, Request, 11
01:00:56, TRX4, Stopping, 01:01:02, Command, 6

关于如何做到这一点的任何想法都会很棒,感谢您的时间。

2 个答案:

答案 0 :(得分:1)

尝试此查询:

SELECT
  TO_CHAR(t.Time, 'HH24:MI:SS') AS "PROCESSOR_EVENT.Time",
  t.Machine AS "PROCESSOR_EVENT.Machine",
  t.Name AS "PROCESSOR_EVENT.Name",
  TO_CHAR(t.ce_time, 'HH24:MI:SS') AS "COMM_EVENT.Time",
  t.ce_type AS "COMM_EVENT.Type",
  (t.ce_time - t.Time)*24*60*60 AS TimeDifference
FROM (
  SELECT pe.*,
    ROW_NUMBER() OVER (PARTITION BY pe.ID ORDER BY ce.Time) AS rn,
    ce.Time AS ce_time,
    ce.Type AS ce_type
  FROM (
    SELECT PROCESSOR_EVENT.*,
      LEAD(Time) OVER (PARTITION BY Machine ORDER BY Time) AS next_pe_time
    FROM PROCESSOR_EVENT
    -- here put WHERE with filtering conditions for PROCESSOR_EVENT table
  ) pe
  LEFT OUTER JOIN COMM_EVENT ce
    ON ce.Machine = pe.Machine
    AND ce.Time > pe.Time
    AND (pe.next_pe_time IS NULL OR ce.Time < pe.next_pe_time)
) t
WHERE t.rn = 1
ORDER BY t.Time

SQL Fiddle

上测试

答案 1 :(得分:0)

有多种方法可以解决这个问题。在执行两个表的并集之后,这是一种多次使用lead()的方法。基本数据是:

select pc.*,
       lead(time) over (partition by machine order by time) as nexttime,
       lead(which) over (partition by machine order by time) as nextwhich,
       lead(type) over (partition by machine order by time) as nexttype
from (select pe.time, pe.machine, pe.machine, pe.name, 'pe' as which
      from processor_event pe
      union all
      select ce.time, ce.machine, ce.name, 'ce' as which
      from comm_event ce
     ) pc;

接下来,我们只需要将您想要的逻辑应用于此数据:

with pc as (
      select pc.*,
             lead(time) over (partition by machine order by time) as nexttime,
             lead(which) over (partition by machine order by time) as nextwhich,
             lead(type) over (partition by machine order by time) as nexttype
      from (select pe.time, pe.machine, pe.name, NULL as type, 'pe' as which
            from processor_event pe
            union all
            select ce.time, ce.machine, ce.name, ce.type, 'ce' as which
            from comm_event ce
           ) pc
     )
select pc.time, pc.machine, pc.name,
       (case when nextwhich = 'ce' then nexttime end) as comm_time,
       (case when nextwhich = 'ce' then nexttype end) as comm_type,
       ((case when nextwhich = 'ce' then nexttime end) - time) as diff
from pc
where pc.which = 'pe';