MySQL嵌套查询计数

时间:2012-05-03 16:41:12

标签: mysql

一些背景信息;这是一个应用程序,允许用户创建挑战,然后对这些挑战进行投票(bog标准userX-vs-userY类型应用程序)。

这里的最终目标是获得5个用户的列表,按照他们赢得的挑战数量排序,以创建一种排行榜。如果用户的状态=已过期并且用户具有>则用户将赢得挑战。 50票对该挑战(挑战在总共100票之后到期)。

我在这里简化了一些事情,但基本上有三个表:

  1. 用户

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

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

    • ID
    • challenge_id
    • USER_ID
    • voted_for
  4. 到目前为止,我有一个内部查询,如下所示:

    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票赞。

    我需要做的是计算此处返回的行数,将其从users表应用于每个用户,按返回的行数排序并将其限制为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.这是否是正确的方式来进行此类查询?谁能说清楚我应该怎么做呢?

    谢谢!

1 个答案:

答案 0 :(得分: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表,这可以提高查询性能 - 但是,它也可能会恶化,您只能在使用实际数据库进行测试后才知道。