Oracle 查询具有特定列平均值的最新行?

Oracle query latest row with average for specific column?

具有以下数据集。我需要一些关于 sql 语句的帮助,它会根据 PING_DATE 和唯一的 PING_DESTINATIONPING_SOURCE 以及添加的 AVG 的列给我最新的行PING_AVG 最近 10 分钟内的所有行。

 PING_DATE            | PACKET_LOSS  | PING_MIN | PING_AVG | PING_MAX | PING_SOURCE | PING_DESTINATION
-------------------------------------------------------------------------------------------------------
 5/5/2015 12:58:18 PM |   0          |  68      |  68      |  72      |  site1      |  orange15
 5/5/2015 12:58:43 PM |   0          |  68      |  71      |  76      |  site1      |  orange15
 5/5/2015 12:59:11 PM |   0          |  68      |  68      |  72      |  site1      |  pear11
 5/5/2015  1:09:47 PM |   0          |  68      |  70      |  76      |  site1      |  pear11
 5/5/2015  1:43:59 PM |   0          |  68      |  69      |  72      |  site1      |  pear11
 5/5/2015  1:45:41 PM |   0          |  68      |  69      |  72      |  site1      |  pear11
 5/5/2015  2:03:43 PM |   0          |  68      |  68      |  72      |  site1      |  pear11
 5/5/2015  3:01:53 PM |   0          |  68      |  68      |  72      |  site1      |  pear11
 5/5/2015  3:02:05 PM |   0          |  68      |  69      |  72      |  site1      |  pear11
 5/5/2015  3:00:59 PM |  20          |  68      |  68      |  68      |  site1      |  pear11
 5/5/2015  3:01:07 PM |   0          |  68      |  68      |  72      |  site1      |  pear11
 5/5/2015  3:01:14 PM |   0          |  68      |  70      |  72      |  site1      |  pear11
 5/5/2015 12:46:55 PM |   3          |   3      |   3      |   3      |  site1      |  lemon1

查询结果:

 PING_DATE            | PACKET_LOSS  | PING_MIN | PING_AVG | PING_MAX | PING_SOURCE | PING_DESTINATION | 10minavg
------------------------------------------------------------------------------------------------------------------
 5/5/2015 12:58:43 PM |   0          |  68      |  71      |  76      |  site1      |  orange15        |  71
 5/5/2015  3:01:14 PM |   0          |  68      |  70      |  72      |  site1      |    pear11        |  65
 5/5/2015 12:46:55 PM |   3          |  3       |   3      |   3      |  site1      |    lemon1        |   3

像这样:

SELECT DISTINCT ping_source, 
   first_value(ping_date) over (partition by ping_source order by ping_date desc),
  first_value(packet_loss) over (partition by ping_source order by ping_date desc)
 -- ... 
FROM data
CROSS JOIN
select avg(ping_avg) from data
where (sysdate - ping_date) * 24 * 60 < 10;

这是基于问题的直接查询。

根据示例输出进行了编辑。从现在开始的最后 10 分钟,在代码段“(i.latest_ping - interval '10' minute)”中使用 systemtimestamp 而不是 i.latest_ping。从 max_ping_time 开始的最后 10 分钟使用 i.latest_ping 作为源-目标对。

select 
    o.*, 
    (select avg(ping_avg) from ping_info a 
        where a.ping_source = i.ping_source
        and a.ping_dest = i.ping_dest
        and a.ping_date >= (systemtimestamp - interval '10' minute)
    ) last_10min_avg 
from ping_info o,
    (select ping_source, ping_dest, max(ping_date) latest_ping
    from ping_info
    group by ping_source, ping_dest) i
where o.ping_source = i.ping_source
and o.ping_dest = i.ping_dest
and o.ping_date = i.latest_ping;

对于 "last 10 minutes average" 是 "last 10 minutes in each group" 这是您要查找的查询:

with xyz as (
    select X.*,
        row_number() over (
            partition by ping_destination, ping_source
            order by ping_date desc
        ) as latest_row#,
        avg(ping_avg) over (
            partition by ping_destination, ping_source
            order by ping_date asc
                range between
                interval '10' minute preceding
                and current row
        ) as the_10_min_avg
    from ping_table X
)
select *
from xyz
where latest_row# = 1
;

对于 "last 10 minutes average" 是 "from 10 minutes ago until now" 这是您要查找的查询:

with xyz as (
    select X.*,
        row_number() over (
            partition by ping_destination, ping_source
            order by ping_date desc
        ) as latest_row#,
        avg(ping_avg) over (
            partition by ping_destination, ping_source
        ) as the_10_min_avg
    from ping_table X
    where X.ping_date >= systimestamp - interval '10' minute
)
select *
from xyz
where latest_row# = 1
;