计算MySQL中的百分比排名

时间:2013-09-25 19:23:13

标签: mysql sql

我有一张包含费用的数据表。对于任何给定的记录,我想知道记录与其他成本相关的位置。

基本上,我想知道(有多少记录的成本较低)/(记录总数)。

到目前为止,我已经提出:

SELECT (SUM(IF(r.cost > c.cost, 1, 0)) + 1) / COUNT(1) as percent_rank 
FROM record r, 
   (SELECT cost FROM record WHERE cost IS NOT NULL) as c 
WHERE r.id = 10;

在此查询上运行EXPLAIN会产生:

+----+-------------+------------+-------+---------------+---------+---------+-------+-------+-------------+
| id | select_type | table      | type  | possible_keys | key     | key_len | ref   | rows  | Extra       |
+----+-------------+------------+-------+---------------+---------+---------+-------+-------+-------------+
|  1 | PRIMARY     | r          | const | PRIMARY       | PRIMARY | 4       | const |     1 |             |
|  1 | PRIMARY     | <derived2> | ALL   | NULL          | NULL    | NULL    | NULL  | 21469 |             |
|  2 | DERIVED     | record     | ALL   | NULL          | NULL    | NULL    | NULL  | 21469 | Using where |
+----+-------------+------------+-------+---------------+---------+---------+-------+-------+-------------+

有没有更好的方法来运行此查询? 21469是表中的所有记录。我有点担心交叉连接,但是这个查询总是以id = something运行,所以它只是1 *总num行。

1 个答案:

答案 0 :(得分:0)

我建议在子查询中获取r.cost的值,或者如果把它放在查询中引用的变量而不是连接中,那么这样可以简化你需要的逻辑:

DECLARE @thisCost Cost_Datatype;
SELECT @thisCost = cost FROM record WHERE id = 10;

表示查询现在看起来像:

SELECT (SUM(IF(@thisCost > cost, 1, 0)) + 1) / COUNT(1) as percent_rank 
FROM record 
WHERE cost IS NOT NULL 

删除了连接的复杂性后,还可以删除条件,并允许引擎通过将总行数放在自己的(子)查询中来作为设置操作来回答查询:

SELECT (Count(*) / (SELECT Count(*) FROM record)) as [% with lower cost]
FROM record
WHERE cost IS NOT NULL AND @thisCost > cost

这样做了吗?