我正在开发一个玩家可以提问的系统。每个玩家被分配到不同的游戏和语言。他们也获得了奖励积分。
我需要一份报告,显示有关提出的问题数量,仍有多少问题,关闭数量以及奖金总额的数据。报告是按游戏和问题类型。
下面的查询工作正常,但现在我必须删除重复的玩家,这样每个玩家只有一个问题(他问的最后一个)。
SELECT
q.game,
q.language,
q.questionType,
COUNT(q.player) AS total,
SUM(IF(q.status = 'Active', 1, 0)) AS active,
SUM(IF(q.status = 'Closed', 1, 0)) AS closed,
SUM(q.points) AS points
FROM questions AS q
LEFT JOIN players AS p ON p.id = q.asked_by
LEFT JOIN games AS g ON g.id = p.game
GROUP BY q.game, q.questionType
答案 0 :(得分:1)
正如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;
答案 1 :(得分:0)
首先,你没有使用游戏桌或玩家桌上的数据,所以不需要加入它们。
SELECT
q.game,
q.language,
q.questionType,
COUNT(q.player) AS total,
SUM(IF(q.status = 'Active', 1, 0)) AS active,
SUM(IF(q.status = 'Closed', 1, 0)) AS closed,
SUM(q.points) AS points
FROM questions AS q
WHERE id IN (SELECT MAX(id) FROM questions GROUP BY player)
GROUP BY q.game, q.questionType
我正在做的是为每个玩家选择最后一个独特的问题,然后在其上运行查询。您的q.language
中没有GROUP BY
,而且它不是聚合函数。不建议你这样做。我们还建议您在群组中加入语言。