中位数(Transact-SQL)

适用于:Microsoft Fabric 中的 SQL 分析终结点和 Microsoft Fabric 中的仓库

该 MEDIAN 函数返回非NULL 数字值的准确中位数,即第50百分位数。 可以将它用作聚合函数和窗口(分析)函数:

  • 总使用量:返回整个组的中位数。
  • 窗口使用:返回每个分区的中位数,同时保持行级输出。

Transact-SQL 语法约定

Syntax

聚合函数语法:

MEDIAN ( numeric_expression )

分析函数语法:

MEDIAN ( numeric_expression ) OVER ( [ <partition_by_clause> ] )

Arguments

numeric_expression

计算中位数的数值表达式。 支持的精确数值类型有 int, bigint, decimalsmallintnumericbittinyintsmallmoney和 。money 支持的近似数值类型有 float 和 real。

OVER 子句

partition_by_clause将子句生成的FROM结果集划分为分区,并将函数应用于每个分区。

如果你没有指定 partition_by_clause,函数会把查询结果集的所有行当作一个分区。

该OVER子句不支持,ROWS也RANGE不支持ORDER BY。MEDIAN

有关详细信息,请参阅 SELECT - OVER 子句(Transact-SQL)。

返回类型

返回 float(53)。

Remarks

MEDIAN 计算有序非NULL 输入值的连续第50百分位。 对于偶数个输入值,函数会在这两个中间值之间插值。 结果可能不是输入行中存在的值。

MEDIAN 等价于 PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY numeric_expression) 聚合使用。 解析形式在每个分区内具有等价的连续百分位语义。

NULL 值将被忽略。 如果所有输入值均为 NULL,或无行符合条件,则 MEDIAN 返回 NULL。 当 ANSI_WARNINGS 时 ON,消除 NULL 值产生标准汇总警告。

MEDIAN 之所以非确定性,是因为在并行执行路径中的浮点计算会产生细微变化。 有关详细信息,请参阅确定性函数和不确定性函数。

不支持 DISTINCT。 不支持字符、日期、时间和日期时间表达。

该MEDIAN功能可在Fabric Data Warehouse和Fabric项的SQL分析端点中获得。 该MEDIAN功能在 SQL Server、Azure SQL 数据库、Azure SQL 托管实例 或 Fabric 中的 SQL 数据库中都不支持。

用例

当平均值可能被异常高低的数值扭曲时使用 MEDIAN 。 例如,中位订单值、响应时间或理领金额通常比算术平均值更清楚地代表典型观察值。 聚合形式总结组,分析形式则在每个细节行中添加一个划分基准。

Examples

A. 计算一个总中位数

该示例返回八个值的中位数。 由于输入行数为偶数,插 MEDIAN 值在4到5行之间。

SELECT MEDIAN(value) AS MedianValue
FROM (VALUES (1), (2), (3), (4), (5), (6), (7), (8)) AS t(value);

结果为 4.5。

B. 计算每个群体的中位数

本例计算每个销售区域的中位订单金额。

WITH SalesOrders AS (
    SELECT *
    FROM (VALUES
        ('North', 120.00),
        ('North', 220.00),
        ('North', 320.00),
        ('South', 150.00),
        ('South', 250.00),
        ('South', 450.00)
    ) AS v(region, order_amount)
)
SELECT
    region,
    MEDIAN(order_amount) AS MedianOrderAmount
FROM SalesOrders
GROUP BY region;

C. 忽略NULL值

该示例忽略输入, NULL 从剩余值计算中位数。

SELECT MEDIAN(value) AS MedianValue
FROM (VALUES (1), (2), (NULL), (3), (4)) AS t(value);

如果每个输入值都是 NULL,函数返回 NULL。

D. 计算一个分区窗口中位数

这个例子将每个服务的中位延迟加到每个请求行。

WITH ServiceLatency AS (
    SELECT *
    FROM (VALUES
        ('Checkout', 'req-001', 180),
        ('Checkout', 'req-002', 220),
        ('Checkout', 'req-003', 260),
        ('Search', 'req-010', 90),
        ('Search', 'req-011', 110),
        ('Search', 'req-012', 130)
    ) AS v(service, request_id, latency_ms)
)
SELECT
    service,
    request_id,
    latency_ms,
    MEDIAN(latency_ms) OVER (PARTITION BY service) AS ServiceMedianLatency
FROM ServiceLatency;