2009-09-11 10 views
5

Mam tabelę, która ma pewną kolumnę numeryczną o nazwie Score. Chciałbym wykonać zapytanie na tej tabeli, którego wynik będzie miał 100 wierszy, każdy reprezentujący wynik odpowiadający temu percentylowi. Na przykład, wynik może wyglądać następująco:SQL: znajdź percentyle

Percentile | Score 
--------------------- 
01   | 10 
02   | 12 
03   | 12 
04   | 17 
...  | ... 
99   | 1684 
100  | 1685 

Wartości wynik w tabeli wyników powyżej są wartościami rzeczywistymi nacięć, które istnieją w szybie, i nie są interpolowane. Wynik interpolacji będzie lepszy, ale nie jest wymagany.

Może być kilka heurystyk, które mogą dać taki wynik. To, czego używam dzisiaj (w kodzie), jest zasadniczo następujące: - Wartość wyniku odpowiadająca percentylowi będzie wartością wyniku, dla której: liczba wierszy z mniejszymi wynikami, podzielona przez całkowitą liczbę wierszy, zaokrąglona do liczby całkowitej , równa się percentyla (mam nadzieję, że to jasne)

mogę rozważyć inne metody heurystyczne, jeśli są one łatwiejsze do wdrożenia

pracuję w MS-SQL, ale doceni rozwiązanie, które działa również na MySQL.

Jaki jest najlepszy sposób, aby to osiągnąć?

+0

Nie jestem pewien, czy to najlepiej wdrożyć to w samym SQL. – Amber

+0

@Dav: Nie jestem też pewien. Próbuję zrozumieć, czy jest to możliwe w SQL i jakie są implikacje wydajności. Z dziesiątkami milionów rekordów, których nie przechowuję w pamięci - może SQL jest najlepszym sposobem. –

+0

@Dav: inny punkt - jeśli uważasz, że nie nadaje się do SQL, a możesz go poprzeć, używając konkretnych argumentów, to jest poprawna ** odpowiedź ** to moja opinia. –

Odpowiedz

5

W SQL Server:

SELECT percentile, score 
FROM (
     SELECT ROW_NUMBER() OVER (PARTITION BY percentile ORDER BY score) AS rn, percentile, score 
     FROM (
       SELECT score, NTILE(100) OVER (ORDER BY score) AS percentile 
       FROM mytable 
       ) q 
     ) q2 
WHERE rn = 1 
+0

Czy można to wykorzystać w podobny sposób na serwerze SQL2000? Mój jest tylko 8.0.2055, więc nie rozpoznaje ROW_NUMBER() ani NTILE() na początek. – Cylindric

+0

Działa również z PostgreSQL. Dzięki. – bortzmeyer

Powiązane problemy