根据Oracle中同一个表中的当前行查找另一行

时间:2012-05-29 15:40:08

标签: sql oracle plsql oracle9i

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

  1. EventID(PK)
  2. 标签名
  3. TagValue
  4. 我需要创建一个类似于:

    的查询
    1. 事件ID
    2. 标签名
    3. TagValue
    4. PreviousConditionTag
    5. PreviousConditionValue
    6. 其中PreviousConditionTag / Value来自前一行的TagName和TagValue(按EventID排序时)。

      在这个问题的更简单版本中,PreviousConditionTag始终与TagName相同 - 也就是说,我只需要检索当前TagName的先前值。我使用Oracle的LAG分析函数解决了这个问题,通过TagName进行分区。

      但是,我现在需要执行类似的操作,但是对于PreviousConditionTag是与TagName相关的任意标记的情况,另一个表中TagName和PreviousConditionTag之间的关系不是一对一的。

      例如,如果给定行的TagName为“ABC”,则关系表可能会说我需要查找“IJK”或“XYZ”的先前值。

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

      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子句,因为分区似乎重叠。 (例如标签ABC需要查看IJK和XYZ,标签DEF需要查看IJK和UVW)

      有什么想法吗?

1 个答案:

答案 0 :(得分:1)

这是答案的重写形式,现在我更了解它。

您想要查找重叠的标记集,并仍然获取上一个事件ID。这个想法如下:

  1. 向映射表添加所有当前标记的标识(因此当前标记=条件标记)
  2. 根据条件标记加入映射表,以获取匹配的当前标记。因此,这些行将被重新标记为&#34; current&#34;他们匹配的标签,您可以使用它来延迟。
  3. 根据滞后逻辑获取最新的EventId,按当前标记进行分区。
  4. 选择Current和Condition标签相同的结果。

    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
    
  5. 这可能看起来很反感,因为你正在通过条件而不是当前向后看东西。而且,您正在乘以正在处理的行数。但是,它可能仍然比您使用的连接解决方​​案更快。