2016-05-24 18 views
4

私は数週間にわたり証券の1週間分の株価データを収集し、「intraday」と呼ばれるテーブルに格納しました。この表には、各取引日の08:01:00〜16:30:00の1分のティックデータが含まれています。sqlの欠落した行に静的データを挿入するにはどうすればよいですか?

証券の中には、毎日1分ごとに取引されないものもあります。取引されていない場合は、行が作成されません(ティックがありません)。私は、これらのダニの取引量が「0」で、以前の株価からの株価を横切るすべての欠けているダニに対して行を挿入することを望んでいました。

例えば、現在は1件のセキュリティのために私が保存されている以下:

ticker  date   tick      cls  volume 

ASC  20151231  1899-12-30 12:30:00  3453  2743 
ASC  20151231  1899-12-30 12:29:00  3449  3490 
ASC  20151231  1899-12-30 12:28:00  3436  930 
ASC  20151231  1899-12-30 12:27:00  3435  255 
ASC  20151231  1899-12-30 12:26:00  3434  4 
ASC  20151231  1899-12-30 12:23:00  3444.59 54 

(各目盛りのための迷惑な1899年12月30日の日付の謝罪 - これらは、それは少し厄介に見えるようにが、害もしません、したがって、なぜ彼らは現在、そこに残る)

私は理想的に保存することがしたい何、これです:

ticker  date   tick      cls  volume 

ASC  20151231  1899-12-30 12:30:00  3453  2743 
ASC  20151231  1899-12-30 12:29:00  3449  3490 
ASC  20151231  1899-12-30 12:28:00  3436  930 
ASC  20151231  1899-12-30 12:27:00  3435  255 
ASC  20151231  1899-12-30 12:26:00  3434  4 
ASC  20151231  1899-12-30 12:25:00  3444.59 0   < new row 
ASC  20151231  1899-12-30 12:24:00  3444.59 0   < new row 
ASC  20151231  1899-12-30 12:23:00  3444.59 54 

ので、それぞれ個別のティッカーと日付値のため、範囲が存在することになります08:01:00〜16:30:00の間の各分の値のいくつかは現在格納されているもので、他のものは0のボリューム値を持ち、前のclose値をコピーするclose値です。

私は絶対に困惑しており、あなたがこれに潜在的に提供する可能性のあるヘルプを感謝します!

大切にしてください。

+0

最初の表では、12:25:00と12:24:00にティッカー 'ASC'の取引がなかったことを忘れていたので、これらの値の記録はありません。私が入力したいこれらの値です。うまくいけば、これは私の2番目の表で明らかですが、それ以上の明確化のためです。どうもありがとう。 – Jambo

+0

これを一度に行う必要がありますか(DBギャップを埋めるか)、将来も機能する必要がありますか? – Dexion

+0

こんにちはDexion - 一気に。私はデータの収集を終了しましたが、今はすべて歴史的にそれを通り、値を追加する必要があります。 – Jambo

答えて

2

再帰的なCTEを使用して、必要な範囲のタイムテーブルを作成します。私はあなたのサンプルからのデータを使用して12分を使用しましたが、それを拡張することができます。最後の非ヌル値の取得は、カーソルを使用せずにややこしいですが、可能です。興味があれば、Hereはもっと詳しい説明です。以下のコードの

デモ:http://rextester.com/QDQR73738

セットアップ:

create table test_data(ticker varchar(5), date integer, tick datetime, cls decimal(10,2), volume integer); 
create table test_data2(ticker varchar(5), date integer, tick datetime, cls decimal(10,2), volume integer); 

insert into test_data 
    select 'ASC', 20151231, '1899-12-30 12:30:00', 3453, 2743 union all 
    select 'ASC', 20151231, '1899-12-30 12:29:00', 3449, 3490 union all 
    select 'ASC', 20151231, '1899-12-30 12:28:00', 3436, 930 union all 
    select 'ASC', 20151231, '1899-12-30 12:27:00', 3435, 255 union all 
    select 'ASC', 20151231, '1899-12-30 12:26:00', 3434, 4 union all 
    select 'ASC', 20151231, '1899-12-30 12:23:00', 3444.59, 54 union all 

    select 'BSC', 20151231, '1899-12-30 12:23:00', 3444.59, 54 union all 
    select 'BSC', 20151231, '1899-12-30 12:28:00', 3436, 930 
; 

クエリ:

Declare @tickers Table (ticker varchar(5)); 
Insert into @tickers select distinct ticker from test_data; 

Declare @ticker varchar(5); 
While exists (Select * From @tickers) 
    BEGIN 
    select @ticker = min(ticker) from @tickers; 

    with cte(tm) 
    as(Select cast('1899-12-30 12:23:00' as datetime) as tm 
     union all 
    Select dateadd(minute, 1, tm) 
     from cte 
     where tm < cast('1899-12-30 12:31:00' as datetime) 
    )  

    insert into test_data2 
    select 
     max(ticker) over (partition by grp order by tick rows unbounded preceding) ticker, 
     max(date) over (partition by grp order by tick rows unbounded preceding) date, 
     tick, 
     max(cls) over (partition by grp order by tick rows unbounded preceding) cls, 
     volume 
    from (
      select 
       ticker, 
       date, 
       tick, 
       cls, 
       volume, 
       id, 
       max(id1) OVER(ORDER BY tick ROWS UNBOUNDED PRECEDING) AS grp 
      from (
       select 
        td.ticker, 
        td.date, 
        coalesce(td.tick, cte.tm) tick, 
        td.cls, 
        coalesce(td.volume, 0) volume, 
        row_number() over (order by tick) id 
       from test_data td 
       right outer join cte 
       on td.tick = cte.tm 
       and td.ticker = @ticker 
     ) cte2 
     CROSS APPLY (VALUES(CASE WHEN ticker IS NOT NULL THEN id END)) 
      AS A(id1) 
    ) cte3; 

     Delete from @tickers where ticker = @ticker; 
    End 

select * from test_data2 
order by ticker, tick; 
+0

ありがとうございます。あなたのデモはすばらしく動作します。 SQL Serverで完全なデータセットを使用してこれを実行しようとすると、次のメッセージが表示されます。 'メッセージ402、レベル16、状態1、行21 datetimeとtimeのデータ型が等しい演算子では互換性がありません。 'time'を 'datetime'に変更すると、このエラーメッセージは消えますが、結果は奇数です(空白の510行のデータ、08:01:00から16:30:00までの分のティック以外)。これは、SQL Server 2008/2012変換ではエラーになる可能性があるので、私はそれを調べますが、それはあなたが気付くだろう迅速な修正を認識しています – Jambo

+0

テーブルからの 'TICK'値cteからの 'TM'値と一致しません。日時に更新したので、それぞれの日付部分が正しく一致していることを確認してください。日付が必要ではないように見えるので、 'キャスト(時間としてTICK) 'することもできます。 – mo2

+0

これは、一度に1つの「TICKER」値に対してのみ機能するとも考えています。あなたが複数のものを試しているのかどうか分からないのですか? – mo2

1

これが動作するかどうかを教えてください。あなたが提供したサンプルデータを使用しましたが、それは欠けている行で動作しました。あなたのレコード数に応じて少し時間がかかるかもしれません。私はテストするテンポラリテーブルを作成しました。ティッカーシンボルごとにこれを1回行う必要があります。

CREATE TABLE #Stocks ( ticker VARCHAR(5), 
        date DATE, 
        tick datetime, 
        cls money, 
        volume money) 

INSERT INTO #Stocks (ticker, date, tick, cls, volume) 
VALUES 
('ASC','2015-12-31','1899-12-30 12:30:00',3453,2743), 
('ASC','2015-12-31','1899-12-30 12:29:00',3449,3490), 
('ASC','2015-12-31','1899-12-30 12:28:00',3436,930), 
('ASC','2015-12-31','1899-12-30 12:27:00',3435,255), 
('ASC','2015-12-31','1899-12-30 12:26:00',3434,4), 
('ASC','2015-12-31','1899-12-30 12:23:00',3444.59,54) 



DECLARE @TotalRows1 INT 
SELECT @TotalRows1 = COUNT(*) FROM #Stocks 
DECLARE @Row INT = 1 
WHILE @Row < @TotalRows1 
BEGIN 
DECLARE @TotalRows INT 
SELECT @TotalRows = COUNT(*) FROM #Stocks 
IF (SELECT DATEADD(MI,1,tick) FROM (SELECT ROW_NUMBER() OVER (ORDER BY tick) RowNumber, * FROM #Stocks) AS T1 WHERE T1.RowNumber = @Row) 
<> 
(SELECT T2.tick FROM (SELECT ROW_NUMBER() OVER (ORDER BY tick) RowNumber, * FROM #Stocks) AS T2 WHERE T2.RowNumber = @Row + 1) 
BEGIN 
INSERT INTO #Stocks 
SELECT T.ticker, T.Date, DATEADD(MI,1,T.tick) tick, T.cls, 0.00 
    FROM (SELECT ROW_NUMBER() OVER (ORDER BY tick) RowNumber, * FROM #Stocks) AS T 
    WHERE T.RowNumber = @Row 
SET @Row = @Row +1 
END 
ELSE 
SET @Row = @Row +1 
END 

SELECT * 
FROM #Stocks 
ORDER BY tick DESC 
+0

私はあなたの助けに感謝します。この場合、ティッカーごとにデータを1つずつテンプレートに持ち込むことができます(ticker、date、tick、cls、advfn.dbo.intradayのtest.dbo.test_stocksへのボリュームを で指定します)ticker = '上記のクエリを実行し、結合されたデータベースに行を挿入し、一時テーブルを削除し、次のティッカーコードで同じプロセスを実行しますか?これは合っているでしょう...約1000のティッカーコードがありますので、数時間かかりますが、手作業よりもはるかに迅速です!これを助けてくれてありがとう。 – Jambo

関連する問題