Oracle SQL,你如何比较一个时间戳并取它之前的数据点?
Oracle SQL, How do you compare a timestamp and take the data point before it?
我有两个 table。我关心的 table 的部分看起来或多或少是这样的。
CAUSEDATE |
____________________________________|
ID | Timestamp |
1 | 01-JAN-15 07.00.01.163000000 |
2 | 01-JAN-15 07.00.30.023000000 |
3 | 01-JAN-15 07.01.01.293000000 |
5 | 01-JAN-15 07.01.11.153000000 |
6 | 01-JAN-15 07.02.01.523000000 |
EVENTS |
___________________________________________________|
ID | Timestamp | INFO |
101 | 01-JAN-15 07.00.01.123000000 | Ker |
102 | 01-JAN-15 07.00.01.233000000 | Bal |
103 | 01-JAN-15 07.00.01.323000000 | Spa |
105 | 01-JAN-15 07.00.01.553000000 | CeP |
106 | 01-JAN-15 07.00.01.633000000 | rog |
我想将 EVENTS 中的时间戳与 CAUSEDATE 中的时间戳相匹配,这样当我通过其时间戳从 CAUSEDATE 中提取 ID = 1 时,它将与 CAUSEDATE 中的 ID 101 匹配,但不匹配任何之后在同一秒内发生。我只对第一个结果感兴趣,对后面的结果不感兴趣。
"EVENTS" 是在 1 毫秒、10 毫秒、有时是 100 毫秒之后注册,这是非常可变的,在某些情况下,它可能超过一秒。所以我正在寻找的是一个解决方案,它查看 CAUSEDATE 中的时间戳,然后查看 EVENTS 中的时间戳在它之前发生(因此它可能是触发 "Cause" 的事件)。
我试过使用 TRUNC(CAUSEDATE.Timestamp, 'MI') = TRUNC(EVENTS.Timestamp, 'MI')
但这太细化了,return 会有太多不相关的信息。没有使用 'SS' 的选项,即便如此,如果输入晚了一点,也无法获取我需要的数据。比如,当它比较 01.993000000 和 02.006000000 时。
如何从 EVENTS.info 中检索 CAUSEDATE 中时间戳之前的第一个实例?所以,它会返回 "Ker" 作为 ID=1 的原因,而不是 "Bal"
对于冗长的解释,我深表歉意。我希望我已经把我的问题说清楚了。
编辑:差点忘记一个重要部分。
我考虑过将时间戳转换为浮点数。
我所做的是使用以下函数
create or replace FUNCTION oracle_to_unix
(
in_date IN DATE)
RETURN NUMBER
IS
BEGIN
RETURN (in_date -TO_DATE('19700101','yyyymmdd'))*86400 - TO_NUMBER(SUBSTR(TZ_OFFSET(sessiontimezone),1,3))*3600;
END;
但这只能找到恰好与起因时间完全同步的事件。我也想要那些没有同时记录的。
如果我没理解错,那么...
select *
from events e1
join causes c on (e1.timestamp = (select max(timestamp)
from events e2
where e2.timestamp < c.timestamp))
我有两个 table。我关心的 table 的部分看起来或多或少是这样的。
CAUSEDATE |
____________________________________|
ID | Timestamp |
1 | 01-JAN-15 07.00.01.163000000 |
2 | 01-JAN-15 07.00.30.023000000 |
3 | 01-JAN-15 07.01.01.293000000 |
5 | 01-JAN-15 07.01.11.153000000 |
6 | 01-JAN-15 07.02.01.523000000 |
EVENTS |
___________________________________________________|
ID | Timestamp | INFO |
101 | 01-JAN-15 07.00.01.123000000 | Ker |
102 | 01-JAN-15 07.00.01.233000000 | Bal |
103 | 01-JAN-15 07.00.01.323000000 | Spa |
105 | 01-JAN-15 07.00.01.553000000 | CeP |
106 | 01-JAN-15 07.00.01.633000000 | rog |
我想将 EVENTS 中的时间戳与 CAUSEDATE 中的时间戳相匹配,这样当我通过其时间戳从 CAUSEDATE 中提取 ID = 1 时,它将与 CAUSEDATE 中的 ID 101 匹配,但不匹配任何之后在同一秒内发生。我只对第一个结果感兴趣,对后面的结果不感兴趣。
"EVENTS" 是在 1 毫秒、10 毫秒、有时是 100 毫秒之后注册,这是非常可变的,在某些情况下,它可能超过一秒。所以我正在寻找的是一个解决方案,它查看 CAUSEDATE 中的时间戳,然后查看 EVENTS 中的时间戳在它之前发生(因此它可能是触发 "Cause" 的事件)。
我试过使用 TRUNC(CAUSEDATE.Timestamp, 'MI') = TRUNC(EVENTS.Timestamp, 'MI')
但这太细化了,return 会有太多不相关的信息。没有使用 'SS' 的选项,即便如此,如果输入晚了一点,也无法获取我需要的数据。比如,当它比较 01.993000000 和 02.006000000 时。
如何从 EVENTS.info 中检索 CAUSEDATE 中时间戳之前的第一个实例?所以,它会返回 "Ker" 作为 ID=1 的原因,而不是 "Bal"
对于冗长的解释,我深表歉意。我希望我已经把我的问题说清楚了。
编辑:差点忘记一个重要部分。
我考虑过将时间戳转换为浮点数。
我所做的是使用以下函数
create or replace FUNCTION oracle_to_unix
(
in_date IN DATE)
RETURN NUMBER
IS
BEGIN
RETURN (in_date -TO_DATE('19700101','yyyymmdd'))*86400 - TO_NUMBER(SUBSTR(TZ_OFFSET(sessiontimezone),1,3))*3600;
END;
但这只能找到恰好与起因时间完全同步的事件。我也想要那些没有同时记录的。
如果我没理解错,那么...
select *
from events e1
join causes c on (e1.timestamp = (select max(timestamp)
from events e2
where e2.timestamp < c.timestamp))