Sql 基于Oracle中同一表中的当前行查找另一行

Sql 基于Oracle中同一表中的当前行查找另一行,sql,oracle,plsql,oracle9i,Sql,Oracle,Plsql,Oracle9i,假设我有一个包含三列的表: EventID PK 标记名 TagValue 我需要创建一个查询,结果如下: 事件 标记名 TagValue 先前条件标记 先前条件值 其中,PreviousConditionTag/Value是根据EventID排序时上一行的标记名和TagValue 在这个问题的简单版本中,PreviousConditionTag始终与标记名相同——也就是说,我只需要检索当前标记名的上一个值。我使用Oracle的滞后分析函数(按标记名分区)解决了这个问题 然而,我现在需要执行类似

假设我有一个包含三列的表:

EventID PK 标记名 TagValue 我需要创建一个查询,结果如下:

事件 标记名 TagValue 先前条件标记 先前条件值 其中,PreviousConditionTag/Value是根据EventID排序时上一行的标记名和TagValue

在这个问题的简单版本中,PreviousConditionTag始终与标记名相同——也就是说,我只需要检索当前标记名的上一个值。我使用Oracle的滞后分析函数(按标记名分区)解决了这个问题

然而,我现在需要执行类似的操作,但对于PreviousConditionTag是由另一个表关联到标记名的任意标记的情况,其中标记名和PreviousConditionTag之间的关系不是一对一的

例如,如果给定行的标记名为ABC,则关系表可能会说我需要查找以前的IJK或XYZ值

我在一个Oracle函数中提出了这个逻辑,该函数对同一个表执行SELECT并查找符合条件的MAXEventID。例如:

SELECT * FROM MyTable WHERE EventID = (
    SELECT MAX(EventID) FROM MyTable WHERE TagName IN (
        SELECT ConditionTagName FROM ConditionMappingTable WHERE TagName = [CurrentTagName]
    )
) AND EventID <= [CurrentEventId]
然而,正如您所想象的,由于这个查询是在MyTable的每一行的函数中执行的,所以我担心它的性能

我试图想办法再次使用Oracle的LAG分析,但我不确定如何为它提供PARTITION子句,因为分区似乎重叠。e、 g.标签ABC需要查看IJK和XYZ,标签DEF需要查看IJK和UVW


有什么想法吗?

这是答案的改写形式,现在我对它有了更好的理解

您希望查找重叠的标记集,但仍能获得上一个事件id。其思想如下:

将所有当前标记的标识添加到映射表中,使当前标记=条件标记 基于条件标记加入映射表,以获取匹配的当前标记。因此,这些行将使用它们匹配的当前标记重新标记,您可以将其用于延迟。 根据滞后逻辑获取最新的EventId,并按当前标记进行分区。 选择当前标记和条件标记相同的结果

select t.*
from (select t.*, mt.CurrentTagName, mt.ConditionTagName,
         lag(EventId, 1, NULL)
         over (partition by mt.CurrentTagName
               order by EventId)
  from t join
       (select CurrentTagName, ConditionTagName
        from ((select CurrentTagName, ConditionTagName
               from ConditionMappingTable mt
              ) union all
              (select distinct CurrentTagName, CurrentTagName
               from ConditionMappingTable mt
              )
             ) mt
       )
       on mt.ConditionTagName = t.tagname
 ) t
on CurrentTagName = ConditionTagName

这可能看起来有悖常理,因为你是根据情况而不是当前情况来回顾事情的。并且,您将乘以正在处理的行数。但是,它可能仍然比您使用的联接解决方案快

这是答案的改写形式,现在我对它有了更好的理解

您希望查找重叠的标记集,但仍能获得上一个事件id。其思想如下:

将所有当前标记的标识添加到映射表中,使当前标记=条件标记 基于条件标记加入映射表,以获取匹配的当前标记。因此,这些行将使用它们匹配的当前标记重新标记,您可以将其用于延迟。 根据滞后逻辑获取最新的EventId,并按当前标记进行分区。 选择当前标记和条件标记相同的结果

select t.*
from (select t.*, mt.CurrentTagName, mt.ConditionTagName,
         lag(EventId, 1, NULL)
         over (partition by mt.CurrentTagName
               order by EventId)
  from t join
       (select CurrentTagName, ConditionTagName
        from ((select CurrentTagName, ConditionTagName
               from ConditionMappingTable mt
              ) union all
              (select distinct CurrentTagName, CurrentTagName
               from ConditionMappingTable mt
              )
             ) mt
       )
       on mt.ConditionTagName = t.tagname
 ) t
on CurrentTagName = ConditionTagName

这可能看起来有悖常理,因为你是根据情况而不是当前情况来回顾事情的。并且,您将乘以正在处理的行数。但是,它可能仍然比您使用的联接解决方案快

在这种情况下,抵消的目的是什么?Oracle LAG分析有一个我可以指定的偏移量,在一个简单的例子中,我只需要给定标记的前一个值,偏移量是1。在这种情况下,偏移量在技术上仍然是1,但分区并不是那么直接。在原始数据中,我要查找的上一个标记可能出现在任何行之前,但在按事件id排序时,它并不总是出现在当前行之前。我很抱歉。我最好理解这个问题,然后重新回答。我可能把ConditionTagName和CurrentTagName倒过来了。没问题,谢谢你再看一眼!您建议按条件而不是当前值进行向后查找,这似乎会产生很大的差异。我重写了我的查询来实现这一点,现在它在不到一秒钟的时间内完成,而不是5秒或6秒之前。谢谢你的帮助!在这种情况下,抵消的目的是什么?Oracle LAG分析有一个我可以指定的偏移量,在一个简单的例子中,我只需要给定标记的前一个值,偏移量是1。在这种情况下,偏移量在技术上仍然是1,但分区并不是那么直接。在原始数据中,我要查找的上一个标记可能出现在任何行之前,但在按事件id排序时,它并不总是出现在当前行之前。我很抱歉。我最好理解这个问题,然后重新回答。我可能把ConditionTagName和CurrentTagName倒过来了。没问题,谢谢你的帮助 国王,再看一眼!您建议按条件而不是当前值进行向后查找,这似乎会产生很大的差异。我重写了我的查询来实现这一点,现在它在不到一秒钟的时间内完成,而不是5秒或6秒之前。谢谢你的帮助!