通过时间戳为多个条目选择最近的行,同时将另一个 table 与当前条目的子字符串连接起来

Selecting the most recent row by timestamp for multiple entries while joining another table with substring of the current one

好吧,标题听起来很复杂,但我真正想做的事情并没有那么复杂。我的表是:

服务状态:

ServiceIdentifier           ServiceStatus   Timestamp

System1-Service1            1               sometimestamp
System1-Service1            1               sometimestamp
System2-Service1            0               sometimestamp
System2-Service1            1               sometimestamp
System1-Service2            1               sometimestamp
System1-Service2            0               sometimestamp
System2-Service2            1               sometimestamp
System2-Service2            1               sometimestamp
System3-Service42           0               sometimestamp

系统名称表:

SystemIdentifier   SystemName

System1            Baconsystem
System2            LoremIpsumSystem
System3            System42

期望的输出:

Baconsystem, Service1, 1, sometimestamp
Baconsystem, Service2, 1, sometimestamp
LoremIpsumSystem, Service1, 1, sometimestamp
LoremIpsumSystem, Service2, 1, sometimestamp
System42, Service42, 0, sometimestamp

SQL 查询 (Oracle) 应该根据时间戳只输出每个 system-service 组合的最新条目。当我试图让每个 system-service 组合只输出一次时,我无法让子字符串上的连接正常工作。感谢任何帮助。

一种可能性是使用函数 substr()、instr()、row_number():

的解决方案
select sn, sv, sst, st 
  from (
    with st as (
      select 
          substr(ServiceIdentifier, 1, instr(ServiceIdentifier, '-')-1) syst,
          substr(ServiceIdentifier, instr(ServiceIdentifier, '-')+1) service, 
          ServiceStatusTable.*
        from ServiceStatusTable)
    select sn.systemname sn, st.service sv, st.servicestatus sst, st.servicetime st,
        row_number() over (partition by systemname, service 
          order by st.servicetime desc) rn
      from st join Systemnametable sn on st.syst = sn.systemidentifier )
  where rn = 1

SQLFiddle

这样做的一种方法是利用 Oracle 正则表达式:

select snt.systemname, sst.service, sst.servicestatus, sst.timestamp
from (select sst.*,
             regexp_substr(ServiceIdentifier, '[^-]+', 1, 1) as system,
             regexp_substr(ServiceIdentifier, '[^-]+', 1, 2) as service,
             row_number() over (partition by ServiceIdentifier
                                order by timestamp desc) as seqnum
      from Servicestatustable sst
     ) sst left join
     Systemnametable snt
     on snt.SystemIdentifier = sst.system
where seqnum = 1;

Here 是此版本的 SQL Fiddle(感谢 Ponder 创建它)。