【问题标题】:Oracle query latest row with average for specific column?Oracle查询具有特定列平均值的最新行?
【发布时间】:2015-05-06 05:12:08
【问题描述】:

拥有以下数据集。我需要一些关于 sql 语句的帮助,该语句将为我提供基于 PING_DATE 的最新行,具有唯一的 PING_DESTINATIONPING_SOURCE,并为过去 10 分钟内的所有行添加了 AVGPING_AVG 列。

 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

【问题讨论】:

  • 给出示例输出...问题不清楚。最好做一个表格来显示输出应该如何显示
  • site1, orange15 没有 71 的 10 分钟平均值,而是 69.5(68+71)/2 = 69.5 ... 还是没有?)
  • site1, pear11 组的相同问题有 10 分钟平均 (68+68+70+68+69)/5 = 68.6。那么,您究竟希望您的“最后 10 分钟平均值”如何工作?

标签: sql oracle average window-functions


【解决方案1】:

对于“过去 10 分钟的平均值”是“每组的最后 10 分钟”,这是您要查找的查询:

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
;

对于“过去 10 分钟平均值”是“从 10 分钟前到现在”,这是您要查找的查询:

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
;

【讨论】:

  • 有效,但我得到的行超过 10 分钟。
  • 您希望行距“现在”不超过 10 分钟??
  • 啊,该死的,你一开始就应该在你的问题中这么说。
【解决方案2】:

类似这样的:

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;

【讨论】:

    【解决方案3】:

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

    根据示例输出进行编辑。从现在开始的最后 10 分钟,在 sn -p "(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;
    

    【讨论】:

    • 有效,但我得到的行超过 10 分钟。
    猜你喜欢
    • 2020-03-30
    • 1970-01-01
    • 2012-01-06
    • 2015-09-04
    • 1970-01-01
    • 1970-01-01
    • 2020-04-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多