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

基于不同时间事件的ORACLE SQL连接表,sql,oracle,Sql,Oracle,我有两张桌子: 处理器\u事件ID、时间、机器、名称、状态 通信事件ID、时间、机器、名称、类型 我要检索处理器\u EVENT.Time和下一个COMM\u事件之间的时间差,该时间差在下一个处理器\u EVENT.Time之前 i、 e.在下一个处理器事件之前发生的处理器事件之后的第一个通信事件 示例数据: 预期回报: 任何关于如何做这件事的想法都会很好,提前感谢您的时间。有多种方法可以解决这个问题。这是一种在合并两个表之后多次使用lead的方法。基本数据如下: select pc.*,

我有两张桌子:

处理器\u事件ID、时间、机器、名称、状态 通信事件ID、时间、机器、名称、类型 我要检索处理器\u EVENT.Time和下一个COMM\u事件之间的时间差,该时间差在下一个处理器\u EVENT.Time之前

i、 e.在下一个处理器事件之前发生的处理器事件之后的第一个通信事件

示例数据:

预期回报:


任何关于如何做这件事的想法都会很好,提前感谢您的时间。

有多种方法可以解决这个问题。这是一种在合并两个表之后多次使用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';
请尝试以下查询:

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

上进行测试,您可以使用滞后和超前功能进行测试。在您的预期回报中,处理器事件4不应该与通信事件4耦合吗?处理器事件3没有相应的通信事件?您说过要在下一个处理器事件之前执行下一个comm事件。在处理器事件3之后,但在下一个处理器事件4之前,不存在任何通信事件。是吗?是的,你是对的,谢谢你指出这一点,我现在已经更新了。哇,我以前没有做过那么高级的SQL。这就是一个问题吗?@Richard Maguire:是的,一个问题。以SELECT开头并以分号结尾的第一个查询是base语句。只是为了举例说明。执行它以查看LEAD和UNION都做了什么。实际查询包含此基本语句。它以分号开头,以分号结尾。啊,好的,谢谢Thorsten。我试图执行第一个查询,但得到错误:ORA-00904:TYPE:invalid identifier 00904。00000-%s:第4行第12列的无效标识符错误在最后一个“select”语句中select pe.time,pe.machine,pe.name是指pc.time,pc.time,pc.machine吗?嗯,这看起来很有希望,但我得到了以下错误:ORA-01799:列可能没有外部连接到子查询01799。00000-柱不能外部连接到柱subquery@RichardMaguire请看重写的查询,它按预期工作hanks@Rimas我想我快让它运行了。我不确定,但您的连接语法是否友好?我必须将左连接更改为左外部连接,否则它将崩溃。但我不知道要把18号线变成什么?最后,PROCESSOR_事件和COMM_事件的大小非常大,每个事件大约有一百万条记录,如果我只想查询特定日期和时间范围之间的结果,我会在您的查询中插入该限制?好的,谢谢。第18行的连接是左连接、右连接、内部连接还是完全连接?@RichardMaguire我简化了查询,现在只有一个连接。我觉得现在更干净、更容易理解了。我已经标记了放置过滤条件的位置。
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';
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