我有一列数据,其中一些是NULL值,我希望从中提取单个第90个百分位值:
ColA
-----
NULL
100
200
300
NULL
400
500
600
700
800
900
1000
对于上述情况,我正在寻找一种技术,当搜索第90百分位数时返回值900,将第80百分位数返回800,等等。类似的函数是AVG(ColA),其返回550以获得上述数据,或MIN(ColA)返回100等
有什么建议吗?
答案 0 :(得分:9)
如果你想准确得到第90个百分位值,不包括NULL,我建议你直接进行计算。以下版本计算行数和行数,并选择适当的值:
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
我将条件放在SELECT子句而不是WHERE子句中,因此您可以轻松获得第50个百分位数,第17个或任何您想要的值。
答案 1 :(得分:4)
WITH
percentiles AS
(
SELECT
NTILE(100) OVER (ORDER BY ColA) AS percentile,
*
FROM
data
)
SELECT
*
FROM
percentiles
WHERE
percentile = 90
注意:如果数据少于100个观察值,则并非所有百分位数都有值。同样,如果您有超过100个观察值,则某些百分位数将包含更多值。
答案 2 :(得分:0)
从SQL Server 2012开始,现在有PERCENTILE_DISC
和PERCENTILE_CONT
逆分布函数。这些(到目前为止)仅可作为窗口函数使用,而不能作为聚合函数使用,因此由于缺少分组功能,您将不得不删除多余的结果,例如通过使用DISTINCT
或TOP 1
:
WITH t AS (
SELECT *
FROM (
VALUES(NULL),(100),(200),(300),
(NULL),(400),(500),(600),(700),
(800),(900),(1000)
) t(ColA)
)
SELECT DISTINCT percentile_disc(0.9) WITHIN GROUP (ORDER BY ColA) OVER()
FROM t
;