2012-05-03 235 views
0

有点背景信息;这是一个应用程序,它允许用户创建挑战,然后对这些挑战进行投票(bog标准userX-vs-userY类型的应用程序)。MySQL嵌套查询计数

这里的最终目标是根据他们赢得的挑战数量得到一个5位用户的列表,以创建一种排行榜。如果用户的状态=过期并且用户对该挑战> 50票(挑战在总共100张表决后失效),则用户赢得挑战。

我会有点简化这里的东西,但本质上有三个表:

  1. 用户

    • ID
    • 用户名
    • ...
  2. 挑战

    • ID
    • ISSUED_TO
    • ISSUED_BY
    • 状态
  3. challenges_votes

    • ID
    • challenge_id
    • user_id说明
    • voted_for

到目前为止,我有一个内部查询,看起来像:

SELECT `challenges`.`id` 
FROM `challenges_votes` 
LEFT JOIN `challenges` ON (`challenges`.`id` = `challenges_votes`.`challenge_id`) 
WHERE `voted_for` = 1 
WHERE `challenges`.`status` = 'expired' 
GROUP BY `challenges`.`id` 
HAVING COUNT(`challenges_votes`.`id`) > 50 

在这个例子中会返回已过期,并在那里挑战的ID与用户ID 1有超过50票赞成票。

我需要做的是计算行数回到这里,它适用于从用户表中的每个用户,通过行数订购回来,把它限制在5

为此我有以下查询:

SELECT `users`.`id`, `users`.`username`, COUNT(*) AS challenges_won 
FROM (
    SELECT `challenges`.`id` 
    FROM `challenges_votes` 
    LEFT JOIN `challenges` ON (`challenges`.`id` = `challenges_votes`.`challenge_id`) 
    WHERE `voted_for` = 1 
    GROUP BY `challenges`.`id` 
    HAVING COUNT(`challenges_votes`.`id`) > 0 
) AS challenges_won, `users` 
GROUP BY `users`.`id` 
ORDER BY challenges_won 
LIMIT 5 

这是有点越来越有,但当然这里的voted_for用户ID始终是1。这甚至去了解这种类型的查询的正确方法吗?任何人都可以阐明我应该如何做到这一点?

谢谢!

+0

嗨,你能否提供关于你的表格结构的更多细节?我认为'challenges_votes'会有user_id,但我在你的查询中找不到它。 –

+0

'challenges_votes'中的voted_for列是投票的用户ID,而user_id是投票本身(与此查询无关)的用户的ID。 – paulbennett

回答

3

我想下面的脚本将解决你的问题:

-- get the number of chalenges won by each user and return top 5 
SELECT usr.id, usr.username, COUNT(*) AS challenges_won 
FROM users usr 
JOIN (
    SELECT vot.challenge_id, vot.voted_for 
    FROM challenges_votes vot 
    WHERE vot.challenge_id IN (  -- is this check really necessary? 
     SELECT cha.id     -- if any user is voted 51 he wins, so 
     FROM challenges cha   -- why wait another 49 votes that won't 
     WHERE cha.status = 'expired' -- change the result? 
    )         -- 
    GROUP BY vot.challenge_id 
    HAVING COUNT(*) > 50 
) aux ON (aux.voted_for = usr.id) 
GROUP BY usr.id, usr.username 
ORDER BY achallenges_won DESC LIMIT 5; 

请允许我提出一个小的考虑条件,关闭一个挑战:如果任何用户后,51票获胜,为什么有必要再等49票不会改变结果?如果这个约束可以被删除,你不必检查challenges表,这可以提高查询性能 - 但是,它也可能会恶化,你只能在测试实际的数据库之后告诉它。

+0

完美 - 谢谢!我们将面临挑战,直到他们达到总共100张选票,以便某些时候我们可以统计用户的总投票数(用户每次挑战可以获得多达100张选票)。 – paulbennett