函数来计算SQL Server中的中位数
根据MSDN,Median在Transact-SQL中不可用作聚合函数。 但是,我想知道是否可以创建此功能(使用创建聚合函数,用户定义函数或其他方法)。
什么是最好的方式(如果可能的话) - 允许计算聚合查询中的中值(假设为数值数据类型)?
有很多方法可以做到这一点,并且性能大幅变化。 以下是Medians,ROW_NUMBER和性能特别优化的解决方案。 当涉及到执行期间生成的实际I / O时,这是一个特别优化的解决方案 - 它看起来比其他解决方案成本更高,但实际上它要快得多。
该页面还包含对其他解决方案和性能测试细节的讨论。 请注意,如果有多个行的中值列的值相同,则使用唯一列作为消除歧义。
与所有数据库性能场景一样,总是尝试使用真实硬件上的实际数据来测试解决方案 - 您永远不知道何时对SQL Server优化器的更改或环境中的特性会使正常速度的解决方案变慢。
SELECT
CustomerId,
AVG(TotalDue)
FROM
(
SELECT
CustomerId,
TotalDue,
-- SalesOrderId in the ORDER BY is a disambiguator to break ties
ROW_NUMBER() OVER (
PARTITION BY CustomerId
ORDER BY TotalDue ASC, SalesOrderId ASC) AS RowAsc,
ROW_NUMBER() OVER (
PARTITION BY CustomerId
ORDER BY TotalDue DESC, SalesOrderId DESC) AS RowDesc
FROM Sales.SalesOrderHeader SOH
) x
WHERE
RowAsc IN (RowDesc, RowDesc - 1, RowDesc + 1)
GROUP BY CustomerId
ORDER BY CustomerId;
如果您使用的是SQL 2005或更高版本,则对于表中的单个列来说,这是一个很好的简单中值计算:
SELECT
(
(SELECT MAX(Score) FROM
(SELECT TOP 50 PERCENT Score FROM Posts ORDER BY Score) AS BottomHalf)
+
(SELECT MIN(Score) FROM
(SELECT TOP 50 PERCENT Score FROM Posts ORDER BY Score DESC) AS TopHalf)
) / 2 AS Median
在SQL Server 2012中,您应该使用PERCENTILE_CONT:
SELECT SalesOrderID, OrderQty,
PERCENTILE_CONT(0.5)
WITHIN GROUP (ORDER BY OrderQty)
OVER (PARTITION BY SalesOrderID) AS MedianCont
FROM Sales.SalesOrderDetail
WHERE SalesOrderID IN (43670, 43669, 43667, 43663)
ORDER BY SalesOrderID DESC
另见:http://blog.sqlauthority.com/2011/11/20/sql-server-introduction-to-percentile_cont-analytic-functions-introduced-in-sql-server-2012/
链接地址: http://www.djcxy.com/p/83821.html