假设我有一个这样的字符表:
(我之所以使用游戏统计信息,只是因为它更易于理解)
id age strength intelligence speed
1 int int int int
2 int int int int
3 int int int int
4 int int int int
5 int int int int
6 int int int int
7 int int int int
... ... ... ... ...
999 int int int int
如何编写MySQL查询来查找30岁以下所有在强度上排在前50位,在智力上排在前50位,在速度上排在前50位的字符?
棘手的部分是此查询将不会被硬编码,它将由前端的代码构造,并且所有条件都是动态的,因此我想拥有一个扁平且可扩展的查询,更好地避免了许多嵌套的JOINS x.id = y.id = z.id的部分在每个JOIN中都会更改,这很难编写。
我已经花了很多时间阅读文档,但是却做得不好。我尝试了WHERE id IN,但是MySQL在这种情况下不支持它。我也读过关于EXISTS的文章,但是文档说它的性能确实很差。
最佳答案
该规范并不清楚“排名前50位”的含义。
假设这意味着按照strength
的顺序获取所有行的前50行,并丢弃/排除其余行...
我建议使用一系列内联视图来分别获取五十个id值,并加入这些集合以获取交集...
SELECT t.id
, t.age
, t.strength
, t.intelligence
, t.strength
FROM ( SELECT qq.id
FROM mytable qq
ORDER BY qq.strength DESC
LIMIT 50
) q
JOIN ( SELECT rr.id
FROM mytable rr
ORDER BY rr.intelligence DESC
LIMIT 50
) r
ON r.id = q.id
JOIN ( SELECT ss.id
FROM mytable ss
ORDER BY ss.speed DESC
LIMIT 50
) s
ON s.id = q.id
JOIN mytable t
ON t.id = q.id
WHERE t.age < 30
ORDER BY ...
为了获得最佳性能,我们需要适当的索引,以避免昂贵的“使用文件排序”操作,例如
... ON mytable (strength, ...)
... ON mytable (intelligence, ...)
... ON mytable (speed, ...)
假设有一个合适的索引,以
id
作为前导列,例如如果是InnoDB,则id
列是PRIMARY KEY(集群索引)。使用EXPLAIN
查看执行计划。关于mysql - 在列1和列2以及列3中找到前50名内排名最高的所有行,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49594613/