正如 ChrisLondon 指出的那样,您不需要大多数表格。该查询的更有效版本是:
SELECT q.game, q.language, q.questionType,
COUNT(q.player) AS total,
SUM(q.status = 'Active') AS active,
SUM(q.status = 'Closed') AS closed,
SUM(q.points) AS points
FROM questions q left outer join
(select player, max(id) as maxid
from questions
group by player
) qp
on q.id = qp.maxid /* don't need the player here because the ids are unique */
GROUP BY q.game, q.language, q.questionType;
MySQL 的许多版本(5.6 之前)在优化子查询方面做得很糟糕。in
为处理的每一行重新运行(甚至可能重新编译)子查询。将其移至from
子句可解决此问题。
这也假设短语“每个玩家只计算一个问题(他问的最后一个问题)”适用于查询中的所有数量。因为它是每个玩家的最后一个,所以您有一些游戏可能没有任何行的风险,因为所有玩家都有新的问题。如果您想要每个游戏的最后一个问题,则将子查询更改为:
SELECT q.game, q.language, q.questionType,
COUNT(q.player) AS total,
SUM(q.status = 'Active') AS active,
SUM(q.status = 'Closed') AS closed,
SUM(q.points) AS points
FROM questions q left outer join
(select game, max(id) as maxid
from questions
group by game
) qg
on q.id = qg.maxid /* don't need the player here because the ids are unique */
GROUP BY q.game, q.language, q.questionType;