【问题标题】:T-SQL: aggregate function for calculating Nth percentileT-SQL:计算第 N 个百分位数的聚合函数
【发布时间】:2019-07-19 11:24:51
【问题描述】:

我正在尝试计算表中单个列中所有值的第 N 个百分位数。我想要的只是一个标量聚合值,其中 N% 的值低于。例如,如果表有 100 行,其中的值与行索引加一(连续 1 到 100)相同,那么我希望这个值告诉我 95% 的值低于 95。

PERCENTILE_CONT 分析函数看起来最接近我想要的。但是如果我尝试这样使用它:

SELECT PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY ValueColumn) OVER () AS P95

我在表格中每行得到一行,所有值都相同。我可以使用TOP 1 只给我其中的一行,但现在我已经完成了额外的表扫描。

我不想创建一个由原始表中的其他列分区的结果的 wizbang 表。我只想要一个聚合的标量值。

编辑:我已经能够在带有WHERE 子句的查询中使用PERCENTILE_CONT。例如:

DECLARE @P95 INT

SELECT TOP 1 @P95 = (PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY ValueColumn) OVER ())
FROM ExampleTable
WHERE LOWER(Color) = 'blue'

SELECT @P95

包含WHERE 子句的结果与没有它时的结果不同。

【问题讨论】:

    标签: sql-server tsql statistics analytics percentile


    【解决方案1】:

    据我所知,您需要在此处执行子查询。例如,要查找严格低于 95% 的记录数,我们可以尝试:

    WITH cte AS (
        SELECT ValueColumn,
            PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY ValueColumn) OVER () AS P95
        FROM yourTable
    )
    
    SELECT COUNT(*)
    FROM cte
    WHERE ValueColumn < P95;
    

    【讨论】:

    • 我再次进行表扫描。更糟糕的是,如果有一个WHERE 子句,我必须将它包含在主查询和子查询中。此外,我不需要基于百分位值的表行的子集。
    • @user1956801 PERCENTILE_CONT 是一个解析函数,它需要遍历整个表才能进行评估。您不能在原始的 WHERE 子句中调用它,因为它还不可用。
    • 所以我不能得到匹配 where 子句的所有行的第 N 个百分位数?
    • 您需要在上述 CTE 中添加 WHERE 子句。
    • 这让我不得不重新进行两次表扫描。如果没有可用的聚合方法并且我无法以这种方式进行优化,我想我可以接受它。
    猜你喜欢
    • 1970-01-01
    • 2012-12-28
    • 2012-11-01
    • 2012-10-28
    • 2012-01-20
    • 2017-07-01
    • 2015-08-01
    • 1970-01-01
    • 2021-03-21
    相关资源
    最近更新 更多