1

我正在开发一个玩家可以提问的系统。每个玩家被分配到不同的游戏和语言。他们也因此获得奖励积分。

我需要一份报告,显示被问的问题数量、仍然活跃的问题数量、关闭的问题数量以及获得的总奖金数量的统计数据。该报告是按游戏和问题类型进行的。

下面的查询工作正常,但现在我必须删除重复的玩家,以便每个玩家只计算一个问题(他问的最后一个问题)。

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
4

2 回答 2

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;
于 2013-05-29T13:26:10.107 回答
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.languageGROUP BY它不是一个聚合函数。不建议您这样做。更建议您在小组中也包括语言。

于 2013-05-29T12:48:30.043 回答