【问题标题】:Alternative for PERCENTILE_CONT in MySQL/MariaDBMySQL/MariaDB 中 PERCENTILE_CONT 的替代方案
【发布时间】:2016-10-14 17:50:14
【问题描述】:

我想在这张表上计算 percentile_cont。 在 Oracle 中,查询将是

SELECT PERCENTILE_CONT(0.05) FROM sometable;

MariaDB/MySQL 中的替代方案是什么?

【问题讨论】:

  • 请根据您的示例表定义percentile_cont 或向我们展示您希望从SELECT 中获得哪些数据。
  • 您需要WITHIN GROUP 功能吗?

标签: mysql oracle mariadb analytic-functions


【解决方案1】:

在 MariaDB 或 MySQL 中都没有内置函数,因此您必须在 SQL 级别解决此问题(或通过添加用 C 编写的用户定义函数...)

这可能有助于提出 SQL 解决方案:

http://rpbouman.blogspot.de/2008/07/calculating-nth-percentile-in-mysql.html

【讨论】:

    【解决方案2】:

    MariaDB 10.2 具有窗口功能。

    对于 MySQL / 较旧的 MariaDB,假设您只想要一组值的第 N 个百分位数。

    这最好在应用代码中完成,但可以内置到存储的例程中。

    1. 统计总行数:SELECT COUNT(*) FROM tbl
    2. 构造并执行带有LIMIT n,1SELECT,其中n 计算为百分位数乘以计数,然后填充到查询中。

    如果您需要在两个值之间进行插值,它会变得更加混乱。你也需要那个吗?

    【讨论】:

    • 是的,但从 10.3.3 开始,它原生支持 PERCENTILE_CONT
    • @lad2025 - 我勾勒出了如何去做。
    【解决方案3】:

    MariaDB 10.3.3 引入了 PERCENTILE_CONTPERCENTILE_DISCMEDIAN 窗口函数。

    PERCENTILE_CONT

    PERCENTILE_CONT()(代表连续百分位数)是一个有序集合聚合函数,也可以用作窗口函数。它返回一个值,该值对应于排序顺序中的给定分数。如果需要,它将在相邻输入项之间进行插值。

    SELECT name, PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY star_rating) 
            OVER (PARTITION BY name) AS pc 
    FROM book_rating;
    

    【讨论】:

      【解决方案4】:

      虽然 MariaDB 10.3.3 以窗口函数 (see Lukasz Szozda's answer) 的形式支持这些函数,但您也可以使用 MySQL 8 中的窗口函数来模拟它们:

      SELECT DISTINCT first_value(matrix_value) OVER (
        ORDER BY CASE WHEN p <= 0.05 THEN p END DESC /* NULLS LAST */
      ) x,
      FROM (
        SELECT
          matrix_value,
          percent_rank() OVER (ORDER BY matrix_value) p,
        FROM some_table
      ) t;
      

      I've blogged about this more in detail here.

      【讨论】:

      • 很好的解决方案,Lukas,但在您的博客上,您只模拟 PERCENTILE_DISC。关于 PERCENTILE_CONT,您只提到它相似但更棘手。你会抽出时间来写一篇模拟 PERCENTILE_CONT 的博文吗?非常感谢。
      • 如果有帮助,我发现这在我的 MySQL 8 上运行速度快了大约 3 倍:SELECT p FROM (SELECT matrix_value, percent_rank() OVER (ORDER BY matrix_value) p, FROM some_table) t WHERE p
      猜你喜欢
      • 1970-01-01
      • 2017-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-19
      • 2013-05-29
      • 2011-08-01
      相关资源
      最近更新 更多