2016-03-31 9 views
0

Sql Server 2014を使用しています。私はすべてのアドオン、SSAS、必要なものをすべて取得できます。Sql Server 2014のパーセンタイルの範囲を計算します。

簡単にするために、整数の列が1つ含まれています。 10^5 - 10^6の行が含まれていると想定するのは安全です。

私は5番目、10番目、15番目... 90番目、95番目のパーセンタイルを計算したいと思います。

私はpercentile_cont(または_disc)を18回呼び出して簡単に実行できます。不幸にも、それは永遠にかかります。

事は、私はそれらの呼び出しが何度も何度も何度も何度も何度もやり直していることを確信しています。

テーブルに対するパーセンタイルの範囲を高速に計算する方法はありますか?

私はC#で簡単に行うことができます。すべての行をメモリにロードして順序付けを行い、0.05 * array.Length項目、0.1 * array.Length項目などを要求します。これは明らかに驚くほど高速です。私はもちろん、テーブル変数やテンポラリテーブルを使ってそれを複製することができますが、いくつかの方法で構築されていないことに驚いています。

+0

別々のクエリではなく、別々の列として 'percentile_cont()'を実行してみてください。 –

+0

パーセンタイルを扱うときは、その用語があいまいであることに注意してください。 https://en.wikipedia.org/wiki/Percentile計算方法がビジネス要件を満たしていることを確認してください。 –

+0

@GordonLinoff - もちろん、それは 'p05、percentile_cont()としてp10、...を選択しました。 'まだ非常に、非常に遅い。 – Gerino

答えて

2

一つの方法は、ntile()および凝集を使用することです:

select nt, min(num), max(num), count(*) 
from (select t.*, ntile(20) over (order by num) as nt 
     from t 
    ) t 
group by nt 
order by nt; 

私はまた、SQL Serverがウィンドウ関数のための列のインデックスを利用する必要があることを追加する必要があります。したがって、インデックスを追加するだけでアプローチをスピードアップすることができます。

+0

'メッセージ1033、レベル15、状態1、行5 TOP、OFFSETまたはFOR XMLも指定されていない限り、ORDER BY句はビュー、インライン関数、派生テーブル、サブクエリ、および共通テーブル式では無効です。 ' – Gerino

+0

Okテーブル からntを選択してnum32、ntile(20)を選択します。) から を選択してから、nt、min(num)、max(num)、count(* group by nt order by nt; ' – Gerino

+0

私はちょうどそれを18パーセンタイルディスクコールと比較しました。そして、それは(非常に速いながら)同じ結果を(最大の列で)与えます。ありがとうございました! – Gerino