假设我有一个包含三列的表:
我需要创建一个类似于:
的查询其中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)
有什么想法吗?
答案 0 :(得分:1)
这是答案的重写形式,现在我更了解它。
您想要查找重叠的标记集,并仍然获取上一个事件ID。这个想法如下:
选择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
这可能看起来很反感,因为你正在通过条件而不是当前向后看东西。而且,您正在乘以正在处理的行数。但是,它可能仍然比您使用的连接解决方案更快。