【发布时间】:2017-11-24 07:26:23
【问题描述】:
我有一个根据列的值计算密集排名的查询:
SELECT id,
score1,
FIND_IN_SET
(
score1,
(
SELECT GROUP_CONCAT(score1 ORDER BY score1 DESC) FROM scores
)
) as rank
FROM score_news;
查询结果如下所示:
+----+--------+------+
| id | score1 | rank |
+----+--------+------+
| 1 | 15 | 1 |
| 2 | 15 | 1 |
| 3 | 14 | 3 |
| 4 | 13 | 4 |
+----+--------+------+
当分数增加 N 倍时,查询需要 Nx 更长的时间。有什么办法可以优化这个吗?我的桌子大小大约为 106
注意:我已经尝试过一种使用 mysql 用户变量的技术,但是当我在大型集合上运行它时得到的结果不一致。经过调查,我在 MySQL 文档中发现了这一点:
用户变量的评估顺序未定义,可能会改变 基于给定查询中包含的元素。在选择 @a,@a := @a+1 ...,你可能会认为 MySQL 会先评估 @a 然后 然后进行第二次分配,但更改查询(例如,通过 添加 GROUP BY、HAVING 或 ORDER BY 子句)可能会更改 评估...一般规则是永远不要给用户赋值 在语句的一部分中使用变量并在某些情况下使用相同的变量 同一语句的其他部分。你可能会得到你想要的结果 期望,但这不能保证。
我对用户变量的尝试:
SELECT
a.id,
@prev := @curr as prev,
@curr := a.score1 as curr,
@rank := IF(@rank = 0, @rank + 1, IF(@prev > @curr, @rank+@ties, @rank)) AS rank,
@ties := IF(@prev = @curr, @ties+1, 1) AS ties
FROM
scores a,
(
SELECT
@curr := null,
@prev := null,
@rank := 0,
@ties := 1,
@total := count(*)
FROM scores
WHERE score1 is not null
) b
WHERE
score1 is not null
ORDER BY
score1 DESC
)
【问题讨论】:
-
我正在尝试计算密集排名,因此两个完全相同的分数将获得相同的排名。
-
它确实给了我密集的行列。
-
为了清楚起见,编辑了我的问题,请检查。
-
你用的是哪个版本的mysql?你能把你的尝试也加入变量吗?
-
@trincot 我已经添加了我的变量尝试,请检查。