获取另一个表中的COUNT()和ID尚不存在的行

时间:2012-12-07 00:41:01

标签: mysql left-join

我有两张桌子:

current_challenges (challenge_id, award_type, award_at_count, expires_in_hours)

user_challenges (user_challenge_id, user_id, challenge_id, awarded)

current_challenges表是挑战的类型,user_challenges表当前是“有效”且已经为不同用户“已完成”的挑战。表格通过challenge_id连接。已完成的挑战是awarded!='0000-00-00 00:00:00',而'有效'是awarded是设定的日期时间。

我想要做的是获取该特定用户尚未完成的随机单challenge_id,但如果该用户中已有2个award_type处于活动状态,则它不应该被选中。

因此,每个用户使用相同的award_type时,最多只能激活2个挑战。

示例:

current_challenges表:

challenge_id    award_type  award_at_count  expires_in_hours
49  1   1   24
50  1   2   24
51  1   3   24
52  2   4   24
53  2   5   24
54  2   6   24

user_challenges表:

user_challenge_id   user_id     challenge_id    awarded
1   8   49  0000-00-00 00:00:00
2   8   50  0000-00-00 00:00:00
3   8   52  2012-12-06 13:58:27
4   11  53  0000-00-00 00:00:00
5   11  54  0000-00-00 00:00:00

对于用户8,challenge_id 49,50将不会被选中,因为它们已经处于活动状态。 51不会因为已经有2个活跃award_type ='1'。 52不会,因为它已经完成,留下53或54作为返回的challenge_id

很抱歉这篇长篇文章,但希望尽可能清楚。我过去一天玩过一次游戏,但是我无处可去...... LEFT JOINHAVING COUNT(),但我无法弄明白......

1 个答案:

答案 0 :(得分:1)

我认为这就是你想要的:

SELECT c.challenge_id
FROM current_challenges AS c
  LEFT JOIN
      ( SELECT cc.award_type                       --- find award types
        FROM current_challenges AS cc              --- with
          JOIN user_challenges AS ac            
            ON ac.challenge_id = cc.challenge_id   --- challenges
        WHERE ac.user_id = 8                       --- for this user
          AND ac.awarded = '0000-00-00'            --- that are active
        GROUP BY cc.award_type
        HAVING COUNT(*) >= 2                       --- and 2 or more
      ) AS ac
      ON ac.award_type = c.award_type
WHERE ac.award_type IS NULL                        --- and exclude them

  AND c.challenge_id NOT IN                        --- then exclude
      ( SELECT challenge_id                        --- any other challenges
        FROM user_challenges AS uc
        WHERE uc.user_id = 8                       --- for this user
      )
ORDER BY RAND()                                    --- order the result randomly
    LIMIT 1 ;                                      --- and choose one