2012-05-03 283 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