1

パラメータ、値、およびそれらの値が記録された時間の表があります。

時間がかかる手順があり、その時間枠で-15/+5秒の時間枠で各パラメーター値の平均結果を取得する必要があります。その上で、時間の経過前に 15 レコードを超えないようにし、時間経過後に 5 レコードを超えないようにしたいと考えています。

たとえば、あるパラメータの値を毎秒記録しているかもしれません。21:30:30 を過ぎた場合、21:30:15 と 21:30:35 の間の値を取得したいと思います。しかし、0.5 秒ごとに記録すると、実際にはその時間枠に収まるパラメーターが必要以上に多くなり、結果を制限する必要が生じます。

私がやろうとしていることとかなり関連しているように見えるこの質問この記事を読みましたが、残念ながら私はMySQLではなくOracleを扱っているので、「制限」を使用できません。

私は現在、次のようなものを持っています:

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 に答える