2012-08-10 12 views
5

Mam kolumny danych, z których niektóre są wartości null, z którego chcą wyodrębnić jednolitego 90. percentyla wartość:T-SQL: Obliczanie n-tego percentyla wartość z kolumny

ColA 
----- 
NULL 
100 
200 
300 
NULL 
400 
500 
600 
700 
800 
900 
1000 

Dla powyższe, szukam techniki, która zwraca wartość 900 podczas wyszukiwania 90 percentyla, 800 dla 80. percentyla, itp. Analogiczną funkcją byłby AVG (ColA), który zwraca 550 dla powyższych danych lub MIN (ColA), który zwraca 100 itd.

Jakieś sugestie?

+0

Czy zawsze będziesz mieć 10 wartości pustych? – Paparazzi

Odpowiedz

9

Jeśli chcesz uzyskać dokładnie 90. percentyla z wyłączeniem wartości NULL, sugerowałbym wykonanie obliczeń bezpośrednio. Poniższa wersja oblicza liczbę wierszy i liczbę wierszy i wybiera odpowiednią wartość:

select max(case when rownum*1.0/numrows <= 0.9 then colA end) as percentile_90th 
from (select colA, 
      row_number() over (order by colA) as rownum, 
      count(*) over (partition by NULL) as numrows 
     from t 
     where colA is not null 
    ) t 

kładę warunek w klauzuli SELECT zamiast klauzuli WHERE, dzięki czemu można łatwo dostać 50. percentyla, 17, lub dowolne wartości, które chcesz.

+0

Jeśli op szuka tylko jednej wartości, aby być 90. percrntile, nie powinna być średnia lub wartość średnia wszystkich 90. petentów? Powiedz, pozycja 90.5 zamiast pozycji 90.0? – MatBailie

+0

@Dems ... Niezupełnie. Ogólnie rzecz biorąc, podział byłby dokładnie wartością 90%, jeśli istnieje. Zgodnie z tradycją tradycyjnie przyjmuje się, że jest to średnia wartości bezpośrednio przed i zaraz po. Średnia 90-tej płytki jest, jak sądzę, bliższa temu, co myślisz. Prawidłowe obliczenia, ale nie to, co nazywałoby 90 percentyla. Może istnieć niezgoda co do tego, co zrobić z duplikatami, ponieważ ta sama wartość może być 80. percentylem i 90. (w obu obliczeniach). –

+0

Przepraszam za późne "zaakceptuj"! Twoja odpowiedź była taka, Gordon. Dzięki jeszcze raz. – jbeldock

4
WITH 
    percentiles AS 
(
    SELECT 
    NTILE(100) OVER (ORDER BY ColA) AS percentile, 
    * 
    FROM 
    data 
) 
SELECT 
    * 
FROM 
    percentiles 
WHERE 
    percentile = 90 


Uwaga: Jeśli dane mniej niż 100 obserwacji, nie wszystkie percentyle będzie mieć wartość. Podobnie, jeśli masz więcej niż 100 obserwacji, niektóre percentyle będą zawierać więcej wartości.

+0

+1 dla 'NTILE'. Zauważ, że jeśli jest mniej niż 100 wartości, powiedzmy tylko 50 wartości ... to percentyl będzie miał wartość "1 - 50" ... więc będzie tylko 90 percentyla, jeśli jest więcej niż 90 wartości. –

+0

Dziękuję. To krok we właściwym kierunku. Edytuję swój post, aby wskazać dwa inne wymagania: dane zawierają wiele NULL i powinny zostać zignorowane, a moim celem jest wyprowadzenie pojedynczej wartości (** ** 90 percentyla). – jbeldock

Powiązane problemy