sql - 如何找到分组的 SQL 中位数

标签 sql sql-server tsql group-by median

我正在使用 SQL Server 2008

如果我有这样的表:

Code   Value
-----------------------
4      240
4      299
4      210
2      NULL
2      3
6      30
6      80
6      10
4      240
2      30

请问如何通过代码列找到中位数 AND 组?
要获得这样的结果集:
Code   Median
-----------------------
4      240
2      16.5
6      30

我真的很喜欢这个中位数的解决方案,但不幸的是它不包括分组依据:
https://stackoverflow.com/a/2026609/106227

最佳答案

当每个组中有奇数个成员时,使用 rank 的解决方案效果很好,即样本中存在中位数,如果成员数为偶数,则 rank 方法会下降,例如

1
2
3
4

这里的中位数是 2.5(即一半的组较小,一半的组较大)但 rank 方法将返回 3。为了解决这个问题,您基本上需要从组的下半部分取最高值,然后组上半部分的底部值,并取两个值的平均值。
WITH CTE AS
(   SELECT  Code,
            Value, 
            [half1] = NTILE(2) OVER(PARTITION BY Code ORDER BY Value), 
            [half2] = NTILE(2) OVER(PARTITION BY Code ORDER BY Value DESC)
    FROM    T
    WHERE   Value IS NOT NULL
)
SELECT  Code,
        (MAX(CASE WHEN Half1 = 1 THEN Value END) + 
        MIN(CASE WHEN Half2 = 1 THEN Value END)) / 2.0
FROM    CTE
GROUP BY Code;

Example on SQL Fiddle

在 SQL Server 2012 中,您可以使用 PERCENTILE_CONT
SELECT  DISTINCT
        Code,
        Median = PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY Value) OVER(PARTITION BY Code)
FROM    T;

Example on SQL Fiddle

关于sql - 如何找到分组的 SQL 中位数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20566513/

相关文章:

mysql - 多个INNER JOIN子查询sql

sql - T-SQL 插入表而无需指定每一列

sql - 如何在动态查询中将行值连接到列名

sql - 从另一个表更新随机行 SQL Server 2014

sql-server - 如果存在(选择 1...)与如果存在(选择 TOP 1 1...)

mysql - 在数据库中拆分表是否有助于解决性能问题?

c# - 创建连接字符串并使用 SQL Server LocalDB

具有限制的 len(n) 的 3 个值的 SQL Server 排列

sql - SQL Server View 中的位置和顶部交互

sql - 想要了解更多关于 NTILE() 的信息