返回作为聚合值的列的Nth Percentile行值

时间:2015-07-08 14:14:30

标签: sql sql-server

与SQL-Server相关

我需要返回与另一列中的多个唯一ID关联的第N个百分位列中的列的值。例如,对于下面的数据集,我需要COL B中每个唯一值的COL B中第80百分位数的值:

COL A       COL B
---------   --------
A           2
A           4
A           6
A           8
A           10
B           2
B           2   
B           3
B           5   
B           7
B           8
B           11  
B           13
B           17
B           18

所需的输出是:

COL A       COL B
--------    --------
A           8
B           13

这是基于以下逻辑:

  

COL B的第80个百分点值是COL A中值A的第4行值8;

     

并且COL B的第80个百分点值是COL A中值B的第8行值13

2 个答案:

答案 0 :(得分:0)

这是一个绝对可怜的查询:

select r.t1, MIN(r.t2) FROM (SELECT TOP 20 PERCENT t1, t2 FROM tempTable where t1 = 'A' ORDER BY t2 desc ) as r
group by r.t1
union
SELECT s.t1, MIN(s.t2) FROM ( SELECT TOP 20 PERCENT t1, t2 FROM tempTable ORDER BY t2 DESC ) as s 
group by s.t1

其中t1是Col A,t2是Col B,tempTable是你的表。 这完全基于您提供的表格,绝不是通用的。

编辑:我想出了如何使用ntile

将其应用于OP的问题
SELECT colA, colB,
        NTILE(5) OVER(PARTITION BY colA ORDER BY colB DESC) AS  'tileN'
FROM tempTable t
group by colA, colB ) as n
where n.tileN = 2

它的作用:

NTile基本上创建100 / a的分区,其中a为NTILE(a)。除以5,我们得到20%的分区。因此2是第80百分位数。然后我们从该查询中选择前20%来消除相同的值。

答案 1 :(得分:0)

如果您使用的是SQL 2012或更高版本,则可以使用percentile_disc()

WITH cte AS (
    SELECT * FROM (VALUES
        ('A', 2  ),
        ('A', 4  ),
        ('A', 6  ),
        ('A', 8  ),
        ('A', 10 ),
        ('B', 2  ),
        ('B', 2  ), 
        ('B', 3  ),
        ('B', 5  ), 
        ('B', 7  ),
        ('B', 8  ),
        ('B', 11 ), 
        ('B', 13 ),
        ('B', 17 ),
        ('B', 18 )
    ) AS x(a, v)
)
SELECT DISTINCT a
    , PERCENTILE_DISC(0.8) WITHIN GROUP (ORDER BY v) OVER (PARTITION BY a)
FROM cte