在 T-SQL 中计算值的中位数

jon*_*inx 3 sql-server t-sql sql-server-2016

我有一段用 T-SQL 编写的代码(存储过程),它将临时表中的多个数据插入表中,如下所示:

INSERT INTO [myschema].[CalculatedData](
    Year, 
    Month,
    Line,
    Car,
    Service,
    Route,
    Trip,
    Stop,
    Qty,
    CalculatedMean
  ) SELECT
    Year,
    Month,
    Line,
    Car,
    Service,
    Route,
    Trip,
    Stop,
    COUNT(*),
    AVG(Duration),  
  FROM
    @TableToCalculate
  GROUP BY
    Year,
    Month,
    Line,
    Car,
    Service,
    Route,
    Trip,
    Stop;
Run Code Online (Sandbox Code Playgroud)

如您所见,我计算了所有值的平均值。很简单,考虑到内置功能

现在,我想做的是计算中位数。没有任何函数可以计算它,但由于中位数等于计算第 50 个百分位数,因此可以使用它。但我不知道该怎么做。

有什么帮助吗?

Pau*_*ite 6

您可以在 Aaron Bertrand 的文章“分组中位数的最佳方法”“计算中位数的最快方法是什么?”中找到主要 SQL Server 方法的调查和性能比较。

通过适当的索引,Peter Larsson 提出的方法通常表现最好,尽管其逻辑有点难以遵循。下面的例子引用自Aaron的第一篇文章,使用了销售数据集:

SELECT d.SalesPerson, w.Median
FROM
(
 SELECT SalesPerson, COUNT(*) AS y
 FROM dbo.Sales
 GROUP BY SalesPerson
) AS d
CROSS APPLY
(
 SELECT AVG(0E + Amount)
 FROM
 (
   SELECT z.Amount
    FROM dbo.Sales AS z
    WHERE z.SalesPerson = d.SalesPerson
    ORDER BY z.Amount
    OFFSET (d.y - 1) / 2 ROWS
    FETCH NEXT 2 - d.y % 2 ROWS ONLY
 ) AS f
) AS w(Median);
Run Code Online (Sandbox Code Playgroud)

您可能还有兴趣阅读我关于使用动态游标计算中位数的文章,该文章的性能出奇的好。我还改进了行编号中位数解决方案,展示了如何进一步提高 Peter 解决方案的性能。

相关问答在这里: