4

たとえば、株式の 3 日移動平均 (実際には 30 日) の出来高を計算しようとしています。最近の 3 つの日付エントリの平均を取得しようとしています (今日から 3 日ではなく)。SQL Server 2012 で行番号を使用して何かをしようとしましたが、成功しませんでした。誰でも助けてもらえますか。以下はテンプレート スキーマであり、SQL での私の無駄な試みです。以下の SQL には、group by を使用したさまざまな化身がありますが、まだ機能していません。どうもありがとう!

select dt_eod, ticker, volume
from
(
  select  dt_eod, ticker, avg(volume)
    row_number() over(partition by dt_eod order by max_close desc) rn
  from mytable
) src
where rn >= 1 and rn <= 3
order by dt_eod

サンプル スキーマ:

CREATE TABLE yourtable  
    ([dt_date] int, [ticker] varchar(1), [volume] int);

INSERT INTO yourtable  
    ([dt_date], [ticker], [volume])
VALUES  
    (20121201, 'A', 5),  
    (20121201, 'B', 7),  
    (20121201, 'C', 6),  
    (20121202, 'A', 10),  
    (20121202, 'B', 8),    
    (20121202, 'C', 7),  
    (20121203, 'A', 10),    
    (20121203, 'B', 87),    
    (20121203, 'C', 74),  
    (20121204, 'A', 10),    
    (20121204, 'B', 86),  
    (20121204, 'C', 67),  
    (20121205, 'A', 100),  
    (20121205, 'B', 84),  
    (20121205, 'C', 70),    
    (20121206, 'A', 258),  
    (20121206, 'B', 864),  
    (20121206, 'C', 740);
4

3 に答える 3

3

各行の3日間の平均:

with top3Values as
(
  select t.ticker, t.dt_date, top3.volume
  from yourtable t
    outer apply
    (
      select top 3 top3.volume
      from yourtable top3
      where t.ticker = top3.ticker
        and t.dt_date >= top3.dt_date
      order by top3.dt_date desc
    ) top3
)
select ticker, dt_date, ThreeDayVolume = avg(volume)
from top3Values
group by ticker, dt_date
order by ticker, dt_date

SQLFiddleデモ

最新の値:

with tickers as
(
  select distinct ticker from yourtable
), top3Values as
(
  select t.ticker, top3.volume
  from tickers t
    outer apply
    (
      select top 3 top3.volume
      from yourtable top3
      where t.ticker = top3.ticker
      order by dt_date desc
    ) top3
)
select ticker, ThreeDayVolume = avg(volume)
from top3Values
group by ticker
order by ticker

SQLFiddleデモ

現実的には、2番目のクエリのティッカーCTEを作成する必要はありません。これは[ticker]テーブルに基づいているため、クエリに何らかのdateパラメーターが含まれている可能性がありますが、これで適切な結果が得られることを願っています。追跡。

于 2013-03-13T21:18:46.980 に答える
2

SQL 2012 について言及されましたが、これは、はるかに単純なパラダイムを活用できることを意味します。

select dt_date, ticker, avg(1.0*volume) over (
    partition by ticker
    order by dt_date
    ROWS BETWEEN 2 preceding and current row
)
from yourtable

実際に達成しようとしていることに関して、これははるかに透明性が高いと思います。

于 2013-03-14T15:16:13.867 に答える
1

ここに示されているさらに別の手法を見たいと思うかもしれません: SQL-Server Moving Averages set-based algorithm with flexible window-periods and no self-joins

このアルゴリズムは非常に高速で (APPLY よりもはるかに高速で、APPLY のように data-points-window が拡大してもパフォーマンスが低下しません)、要件に簡単に適応でき、SQL2012 より前のバージョンで動作し、SQL-2012 のウィンドウ機能の制限を克服します。 OVER/PARTITION-BY 句でウィンドウ幅をハードコーディングする必要があります。

価格平均が移動する株式市場タイプのアプリケーションの場合、ユーザーが平均に含まれるデータポイントの数を変更できるようにすることが一般的な要件です(ユーザーが 7 日、30 日を選択できるように、UI の選択から)。日、60 日など)、および SQL-2012 の OVER 句は、動的 SQL なしではこの可変パーティション幅の要件を処理できません。

于 2013-10-10T19:42:43.427 に答える