lha*_*hne 19 mysql rank percentile
我在MySQL中有一个非常大的测量数据表,我需要为这些值中的每一个计算百分等级.Oracle似乎有一个名为percent_rank的函数,但我找不到类似MySQL的东西.当然,我可以在Python中强制使用它,我仍然使用它来填充表格,但我怀疑这样做效率很低,因为一个样本可能有200,000个观察值.
mat*_*ler 19
这是一种不需要连接的不同方法.在我的情况下(一个包含15,000+的表)行,它在大约3秒内运行.(JOIN方法需要更长的数量级).
在示例中,假设measure是您计算百分比排名的列,而id只是行标识符(不是必需的):
SELECT
id,
@prev := @curr as prev,
@curr := measure as curr,
@rank := IF(@prev > @curr, @rank+@ties, @rank) AS rank,
@ties := IF(@prev = @curr, @ties+1, 1) AS ties,
(1-@rank/@total) as percentrank
FROM
mytable,
(SELECT
@curr := null,
@prev := null,
@rank := 0,
@ties := 1,
@total := count(*) from mytable where measure is not null
) b
WHERE
measure is not null
ORDER BY
measure DESC
Run Code Online (Sandbox Code Playgroud)
这种方法的功劳归功于Shlomi Noach.他在这里详细描述:
http://code.openark.org/blog/mysql/sql-ranking-without-self-join
我已经在MySQL中测试了它并且效果很好; 不知道Oracle,SQLServer等
SELECT
c.id, c.score, ROUND(((@rank - rank) / @rank) * 100, 2) AS percentile_rank
FROM
(SELECT
*,
@prev:=@curr,
@curr:=a.score,
@rank:=IF(@prev = @curr, @rank, @rank + 1) AS rank
FROM
(SELECT id, score FROM mytable) AS a,
(SELECT @curr:= null, @prev:= null, @rank:= 0) AS b
ORDER BY score DESC) AS c;
Run Code Online (Sandbox Code Playgroud)
这是一个相对丑陋的答案,说出来我感到内疚。也就是说,它可能会帮助您解决问题。
确定百分比的一种方法是计算所有行的数量,并计算大于您提供的数量的行数。您可以计算大于或小于,并根据需要取倒数。
对您的号码创建索引。总计=选择计数();less_equal = select count( ) 其中 value > indexed_number;
百分比类似于: less_equal / Total 或 (total - less_equal)/total
确保它们都使用您创建的索引。如果不是,请调整它们直到它们为止。解释查询应该在右侧列中包含“使用索引”。在 select count(*) 的情况下,InnoDB 应该使用索引,MyISAM 应该使用 const 之类的东西。MyISAM 随时都会知道这个值,而无需计算它。
如果您需要将百分比存储在数据库中,则可以使用上面的设置来提高性能,然后使用第二个查询作为内部选择来计算每行的值。第一个查询的值可以设置为常量。
这有帮助吗?
雅各布
| 归档时间: |
|
| 查看次数: |
35177 次 |
| 最近记录: |