【发布时间】:2013-06-12 08:08:06
【问题描述】:
我很喜欢这个。希望我可以在纯 sql 中完成,但此时任何解决方案都可以。
我有ta 和tb 表,其中包含大约同时发生的事件列表。目标是在tb 上从ta 中找到“孤儿”记录。例如:
create table ta ( dt date, id varchar(1));
insert into ta values( to_date('20130101 13:01:01', 'yyyymmdd hh24:mi:ss') , '1' );
insert into ta values( to_date('20130101 13:01:02', 'yyyymmdd hh24:mi:ss') , '2' );
insert into ta values( to_date('20130101 13:01:03', 'yyyymmdd hh24:mi:ss') , '3' );
create table tb ( dt date, id varchar(1));
insert into tb values( to_date('20130101 13:01:5', 'yyyymmdd hh24:mi:ss') , 'a' );
insert into tb values( to_date('20130101 13:01:6', 'yyyymmdd hh24:mi:ss') , 'b' );
但是假设我必须使用 +-5 秒的阈值。因此,要查找的查询类似于:
select
ta.id ida,
tb.id idb
from
ta, tb
where
tb.dt between (ta.dt - 5/86400) and (ta.dt + 5/86400)
order by 1,2
(小提琴:http://sqlfiddle.com/#!4/b58f7c/5)
规则是:
- 事件映射为 1 到 1
-
tb上与ta中给定事件最接近的事件将被视为正确映射。
也就是说,结果查询应该返回类似
IDA | IDB
1 | a
2 | b
3 | null <-- orphan event
尽管我在这里提出的示例查询准确地显示了我遇到的问题。当时间重叠时,很难系统地选择正确的行。
dense_rank() 似乎是选择正确行的答案,但是什么分区/排序会使它们正确?
值得一提,我在 Oracle 11gR2 上执行此操作。
【问题讨论】:
-
这听起来很困难,我认为有一些要求需要澄清。例如,为什么
1匹配到a,而3和a匹配更接近? (你想按 ta.dt 的顺序消费记录吗?)另外,如果有平局怎么办?例如,如果有两个“b”行怎么办?一行匹配 2,另一行匹配 3,还是都匹配 2? -
根据您的定义,孤儿应该是 3
-
@jonearles 你是对的,这可能需要一些澄清。不过这里的主要规则是事件被映射为 1 到 1。这实际上意味着“事件被消耗”一旦匹配——我不想不提这一点,因为它似乎暗示了一个可能变得过于复杂的迭代过程。在平局的情况下,任何一个记录都可以。理想情况下会按时间顺序排列,但只要尊重 1 对 1 映射,这并不重要。我回答你的问题了吗?
-
@haki 这就是我想要展示的。
ta.ia = 3在tb上没有通讯记录。
标签: sql oracle sorting range dense-rank