1

我有一个参数表,值和记录这些值的时间。

我有一个需要时间的程序,并且需要在该时间范围内 -15/+5 秒的时间窗口内获得每个参数值的平均结果。最重要的是,我想确保在过去的时间之前不超过 15 条记录,之后不超过 5 条记录。

例如,也许我每秒都在记录一些参数的值。如果我在 21:30:30 的时间过去,我想获得 21:30:15 和 21:30:35 之间的值。但如果我每半秒记录一次,我实际上会拥有比我想要的更多的适合那个时间框架的参数,这就是我需要限制我的结果的地方。

我已经阅读了这个问题这篇文章,它们似乎与我正在尝试做的事情非常相关,但不幸的是我正在处理 Oracle 而不是 MySQL,所以我不能使用“限制”。

我目前有一些看起来像这样的东西:

std_values as
(
    select
        V.ParameterId,
        V.NumericValue,
    from
        ValuesTable V 
    where
        V.ValueSource = pValueSource 
        and V.Time >= pSummaryTime - 15/86400
        and V.Time <= pSummaryTime + 5/86400
)
select
    ParameterId,
    avg(NumericValue) as NumericValue
from 
    std_values
group by 
    ParameterId

pValueSource只是让我过滤掉我正在查看的值类型的东西,并且pSummaryTime是我基于时间框架的输入时间。这里的目标是获取该pSummaryTime窗口之前的 15 条记录,以及之后的 5 条记录,并将其用作平均值。目前我并没有限制“之前”和“之后”结果的数量,所以我最终得到了落在该时间窗口内的所有内容的平均值。如果没有“限制”之类的东西,我不确定如何在 Oracle 中执行此操作。

4

2 回答 2

3

听起来你想要一个移动窗口聚合函数。这是 Oracle 分析功能特性的一部分。

这不是我的强项,而且由于您没有包含示例表/数据来构建测试用例,所以我只会将您指向 Oracle 文档,这里是: http: //docs.oracle.com/cd/B14117_01/ server.101/b10736/analysis.htm#i1006709

你可能想要这样的东西:

AVG(NumericValue) over (order by pSummaryTime RANGE BETWEEN 15 PRECEDING AND 5 FOLLOWING)

但是,就像我说的那样,不是我的强项,而且完全未经测试,但是,我希望它能传达这个想法。

希望有帮助。

于 2012-07-03T15:43:42.780 回答
0

感谢Mark Bobak 的回答让我走上了正轨,我最终得到了这个解决方案。

with 
values_before as
(
    select
        V.ParameterId,
        V.NumericValue,
        row_number() over (Partition by V.ParameterId order by V.Time desc) as RowNumber
    from
        ValuesTable V
    where
            V.ValueSource = pValueSource 
        and V.Time >= pSummaryTime - 15/86400
        and V.Time <= pSummaryTime
),
values_after as
(
    select
        V.ParameterId,
        V.NumericValue,
        row_number() over (Partition by V.ParameterId order by V.Time desc) as RowNumber
    from
        ValuesTable V
    where
            V.ValueSource = pValueSource 
        and V.Time <= pSummaryTime + 5/86400
        and V.Time > pSummaryTime
),
values_all as
(
    select * from values_before where RowNumber <= 15
    union all
    select * from values_after where RowNumber <= 5
)
select ParameterId, avg(NumericValue) from values_all group by ParameterId 

毫无疑问,有更好的方法可以做到这一点,但它至少似乎给出了正确的结果。关键是使用分析函数来设置前 15 和后 5 的行号和顺序,然后将我的结果过滤到这些。

于 2012-07-03T17:38:20.830 回答