2016-03-31 10 views
0

Ich benutze Sql Server 2014, ich kann alle Add-ons, SSAS, was auch immer benötigt wird.Berechnen Bereich von Perzentilen in Sql Server 2014

Ich habe eine Tabelle, die der Einfachheit halber eine einzelne Spalte mit ganzen Zahlen enthält. Es kann davon ausgegangen werden, dass es 10^5 - 10^6 Zeilen enthält.

Ich möchte das 5., 10., 15. ... 90., 95. Perzentil berechnen.

Ich kann es ziemlich einfach tun, indem Sie propertile_cont (oder _disc) 18 Mal aufrufen. Leider dauert es ewig.

Die Sache ist, ich bin ziemlich sicher, dass diese Anrufe immer und immer wieder dasselbe tun.

Gibt es eine Möglichkeit, eine Reihe von Perzentilen über eine Tabelle schneller zu berechnen?

Ich kann dies leicht in C#, indem Sie alle Zeilen in den Speicher laden, bestellen sie, und nur für 0,05 * array.Length Element, 0,1 * array.Length Artikel usw. - und es ist offensichtlich unglaublich schnell. Ich kann das natürlich replizieren, indem ich eine Tabellenvariable oder eine temporäre Tabelle verwende, aber ich bin überrascht, dass es keine eingebaute Methode gibt.

+0

Versuchen Sie, 'percentile_cont() 'als separate Spalten statt als separate Abfragen auszuführen. –

+0

Wenn Sie mit Perzentilen arbeiten, beachten Sie, dass der Begriff nicht eindeutig ist. https://en.wikipedia.org/wiki/Percentile. Stellen Sie sicher, dass die Berechnungsmethode Ihren Geschäftsanforderungen entspricht. –

+0

@GordonLinoff - ja, natürlich - es war 'wählen Sie percentile_cont() als p05, percentile_cont() als p10, ...'. Immer noch sehr, sehr langsam. – Gerino

Antwort

2

Eine Methode ist ntile() und Aggregation verwenden:

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; 

ich auch, dass SQL Server sollte die Verwendung eines Index für die Spalte für die Fensterfunktionen machen sollte hinzufügen. Sie können also Ihren Ansatz beschleunigen, indem Sie einfach einen Index hinzufügen.

+0

'Msg 1033, Ebene 15, Status 1, Zeile 5 Die ORDER BY-Klausel ist in Sichten, Inline-Funktionen, abgeleiteten Tabellen, Unterabfragen und allgemeinen Tabellenausdrücken ungültig, wenn TOP, OFFSET oder FOR XML ebenfalls angegeben sind. – Gerino

+0

Ok , jetzt funktioniert es: 'wählen Sie nt, min (num), max (num), count (*) von ( wählen Sie num, ntile (20) über (bestellen von table.num) als nt aus Tabelle ) a group by nt order by nt; ' – Gerino

+0

Ich habe es nur mit dem 18-percentile_disc-Aufruf verglichen, und es gibt das gleiche Ergebnis (in der Spalte max), während es immens schneller ist. Vielen Dank! – Gerino