【问题标题】:Select nth percentile from MySQL从 MySQL 中选择第 n 个百分位数
【发布时间】:2011-03-05 04:44:28
【问题描述】:

我有一个简单的数据表,我想从查询中选择大约 40% 的行。

我现在可以做到这一点,首先查询行数,然后运行另一个查询来排序并选择第 n 行:

select count(*) as `total` from mydata;

可能会返回类似 93, 93*0.4 = 37

select * from mydata order by `field` asc limit 37,1;

我可以将这两个查询合并为一个查询吗?

【问题讨论】:

  • @OMG Ponies:我假设 COUNT 返回 93,所以第 40 个百分位大约是第 37 行 (93 * 0.4)。

标签: mysql count percentile


【解决方案1】:

这将为您提供大约第 40 个百分位,它返回 40% 的行小于它的行。它根据行与第 40 个百分位的距离对行进行排序,因为没有行可能正好落在第 40 个百分位上。

SELECT m1.field, m1.otherfield, count(m2.field) 
  FROM mydata m1 INNER JOIN mydata m2 ON m2.field<m1.field
GROUP BY 
   m1.field,m1.otherfield
ORDER BY 
   ABS(0.4-(count(m2.field)/(select count(*) from mydata)))
LIMIT 1

【讨论】:

    【解决方案2】:

    作为一个徒劳的练习(您当前的解决方案可能会更快且更受欢迎),如果表是 MYISAM(或者您可以使用 InnoDB 的近似值):

    SET @row =0;
    SELECT x.*
    FROM information_schema.tables
    JOIN (
      SELECT @row := @row+1 as 'row',mydata.*
      FROM mydata
      ORDER BY field ASC
    ) x
    ON x.row = round(information_schema.tables.table_rows * 0.4)
    WHERE information_schema.tables.table_schema = database()
    AND information_schema.tables.table_name = 'mydata';
    

    【讨论】:

      【解决方案3】:

      还有this 解决方案,它使用了 GROUP_CONCAT 制作的怪物字符串。我必须像这样提高输出的最大值才能使其工作:

      SET SESSION group_concat_max_len = 1000000;
      

      MySql 向导:随意评论这些方法的相对性能。

      【讨论】:

      • 一般来说,您应该尝试包含您发布的任何链接的相关部分。这使人们更容易浏览答案,并确保即使链接消失,答案仍然相关。
      猜你喜欢
      • 2012-12-28
      • 2019-02-28
      • 1970-01-01
      • 2022-01-12
      • 2010-11-10
      • 1970-01-01
      • 2021-09-28
      • 2014-07-25
      • 1970-01-01
      相关资源
      最近更新 更多