2017-12-06 15 views
3

datetimedateフィールドを含む大きなテーブルがあります。 datetimeという2つのリスト、すなわちafromsatosというリストを入力として受け取る関数の一部として、これらの各数値の間に日付がある大きなテーブルのすべての行をこれらのそれぞれについて計算したいと思います。このクエリには、よりスケーラブルなサブ選択肢がありますか?

私はこれを行うには非常に効率的ではない方法は、それが深刻なスケーラビリティの欠点がある。すなわち働い:

/ t1 contains my afrom,ato pairs 
q)t1:([] afrom:`datetime$(2017.10.01T10:00:00.000 2017.10.02T10:00:00.000);ato:`datetime$(2017.10.01T12:00:00.000 2017.10.02T12:00:00.000)); 
q)t1 
afrom     ato      
----------------------------------------------- 
2017.10.01T10:00:00.000 2017.10.01T12:00:00.000 
2017.10.02T10:00:00.000 2017.10.02T12:00:00.000 

/t2 contains my very very large dataset 
q)t2:([] date:`datetime$(2017.10.01T10:01:00.000 2017.10.01T10:02:00.000 2017.10.01T10:03:00.000 2017.10.02T10:01:00.000 2017.10.02T10:02:00.000 2017.10.02T10:03:00.000); ccypair:(3#`EURUSD),(3#`USDCHF); mid:6?1.05); 
q)t2 
date     ccypair mid     
---------------------------------------------------- 
2017.10.01T10:01:00.000 EURUSD 0.24256133290473372 
2017.10.01T10:02:00.000 EURUSD 0.091602176288142809 
2017.10.01T10:03:00.000 EURUSD 0.10756538207642735 
2017.10.02T10:01:00.000 USDCHF 0.91046513157198206 
2017.10.02T10:02:00.000 USDCHF 0.76424539103172717 
2017.10.02T10:03:00.000 USDCHF 0.17090452200500295 

それから私はこのようにcrossを使用することができます。

select from (t1 cross t2) where afrom<date,date<ato 

とこれが正しいを生成結果:

afrom     ato      date     ccypa.. 
-----------------------------------------------------------------------------.. 
2017.10.01T10:00:00.000 2017.10.01T12:00:00.000 2017.10.01T10:01:00.000 EURUS.. 
2017.10.01T10:00:00.000 2017.10.01T12:00:00.000 2017.10.01T10:02:00.000 EURUS.. 
2017.10.01T10:00:00.000 2017.10.01T12:00:00.000 2017.10.01T10:03:00.000 EURUS.. 
2017.10.02T10:00:00.000 2017.10.02T12:00:00.000 2017.10.02T10:01:00.000 USDCH.. 
2017.10.02T10:00:00.000 2017.10.02T12:00:00.000 2017.10.02T10:02:00.000 USDCH.. 
2017.10.02T10:00:00.000 2017.10.02T12:00:00.000 2017.10.02T10:03:00.000 USDCH.. 

ただし、012の大きなリストとatoscrossは、潜在的に大きなテーブルt2のサイズをt1倍に「不必要に」展開し、それはうまく拡張されません。

これを行うより良い方法はありますか?例えば私はのようなものを試してみました:

select from t2 where (exec afrom from t1)<date,date<(exec ato from t1) 
error: `length 

私が推測するループを実行する必要がありますが方法がわからないでしょう。 Subquestion .. afromsatosを分離するのではなく、間隔タプル、すなわちintervals(afrom;ato)のsigleリストを持つことは可能ですか?

答えて

1

私はこれを正しく理解していれば、その後これを実行するための1つの方法はt1の各行を使っだろうと、任意の行がwithin各時間帯落ちる場所を見つける:、

select from t2 where any date within/:value each t1 
date     ccypair mid 
----------------------------------------- 
2017.10.01T10:01:00.000 EURUSD 0.41239 
2017.10.01T10:02:00.000 EURUSD 0.5429457 
... 

上記の夜の出力例と同じですafromatoの列はありません。この例では、範囲内のすべての値を選択し、anyと各右/:を使用すると、複数の範囲を使用できます。これがあなたのために特によくスケールしないなら、あなたは個別にt1の各行に取り組むことができます。

ウィンドウが重ならない場合は動作するはずです
raze{[x;y]select from x where date within value y}[t2]'[t1] 

を。

あなたが排他必要か、あなたはそれらが除外されていることを確認するために、わずかにウィンドウ時間を変更してみてください可能性がある場合:

q)select from t2 where any date within/:value each @[t1;`afrom`ato;+;1 -1*00:00:00.001] 
date     ccypair mid 
----------------------------------------- 
2017.10.01T10:01:00.000 EURUSD 0.41239 
2017.10.01T10:02:00.000 EURUSD 0.5429457 
... 

あなたが選択した行でそれらを横断することができ、出力にafromato列を追加するには:

raze{[x;y]flip[1#'y]cross select from x where date within value[y]+1 -1*00:00:00.001}[t2]'[t1] 
afrom     ato      date     ccypair mid 
----------------------------------------------------------------------------------------- 
2017.10.01T10:00:00.000 2017.10.01T12:00:00.000 2017.10.01T10:01:00.000 EURUSD 0.41239 
2017.10.01T10:00:00.000 2017.10.01T12:00:00.000 2017.10.01T10:02:00.000 EURUSD 0.5429457 
... 
+0

ありがとうございました!残念ながら私の中では排他的な**が必要であることに注意してください。 –

+0

実際には、値が2つのウィンドウに入ると除外されるか、または境界時間が除外されることを意味しますか? –

+0

こんにちはトーマス、お問い合わせいただきありがとうございます。境界時間は除外されているので、 'within'は使用できません。 'afrom、ato'にマッチがないとき、それは行を与えません。 –

関連する問題