2014-03-06 74 views
0

这是一个相当具体的问题。但是过去几个小时我一直在墙上敲打我的头,所以我会尽我所能地尽力解释它。带条件的SQL子查询计数

比方说,我有:

  • 用户
  • 出场数(与用户的联系,有一个创建日期)
  • 徽章解锁(与用户和游戏联系起来,有一个创建日期)

我正在寻找一个查询,列出所有为特定用户解锁的徽章以及用户在解锁徽章前玩过多少游戏。

SELECT users.id, 
     games.id, 
     badge.id, 
     games.created game_created, 
     users_badges.created AS badge_created, 
     subquery.nb_games 
    FROM badges 
     INNER JOIN users_badges 
        ON badges.id = users_badges.badge_id 
     INNER JOIN users 
        ON users_badges.user_id = users.id 
     INNER JOIN games 
        ON users.id = games.user_id 
     INNER JOIN (SELECT user_id, 
          created, 
          COUNT(*) AS nb_games 
         FROM games 
        GROUP BY 
          user_id 
        ) subquery 
        ON subquery.user_id = users.id 
        AND subquery.created <= users_badges.created 
WHERE users.id = 1 

GROUP BY声明显然无效我加入的条件和我最终总是获得的比赛场次总数:

+----------+----------+----------+----------+---------------------+---------------------+ 
| users.id | games.id | badge.id | nb_games | game_created  | badge_created  | 
+----------+----------+----------+----------+---------------------+---------------------+ 
| 1  | 1  | 1  | 3  | 2014-03-12 00:00:00 | 2014-03-12 00:00:00 | 
+----------+----------+----------+----------+---------------------+---------------------+ 
| 1  | 2  | 2  | 3  | 2014-03-13 00:00:00 | 2014-03-13 00:00:00 | 
+----------+----------+----------+----------+---------------------+---------------------+ 
| 1  | 3  | 3  | 3  | 2014-03-14 00:00:00 | 2014-03-14 00:00:00 | 
+----------+----------+----------+----------+---------------------+---------------------+ 

虽然我期望的东西沿着线较为缓慢:

+----------+----------+----------+----------+---------------------+---------------------+ 
| users.id | games.id | badge.id | nb_games | game_created  | badge_created  | 
+----------+----------+----------+----------+---------------------+---------------------+ 
| 1  | 1  | 1  | 1  | 2014-03-12 00:00:00 | 2014-03-12 00:00:00 | 
+----------+----------+----------+----------+---------------------+---------------------+ 
| 1  | 2  | 2  | 2  | 2014-03-13 00:00:00 | 2014-03-13 00:00:00 | 
+----------+----------+----------+----------+---------------------+---------------------+ 
| 1  | 3  | 3  | 3  | 2014-03-14 00:00:00 | 2014-03-14 00:00:00 | 
+----------+----------+----------+----------+---------------------+---------------------+ 

这可能吗?

+0

你的子查询'SELECT user_id,created,COUNT(*)AS nb_games FROM games GROUP BY user_id'总是返回玩家列表和总玩的游戏...这就是为什么你总是获得总玩的游戏数量...看看是否你可以添加像'SUM(IF(game.created cyadvert

回答

1

这可以在没有子查询的情况下实现。就像你的情况一样,你首先在子查询中计算每个用户的游戏数量(因此是计算每个用户的总数),并且在完成之后,您正在尝试检查游戏日期。

另外我看到一个问题,你有两次连接游戏,如果你需要用户 - 徽章 - 游戏之前并不需要。只有一次在您的要求

这里是如何能够sloved

SELECT users.id, 
    game.id, 
    badge.id, 
    users_badges.created AS badge_created, 
    COUNT(gamesBefore.id)_games 
FROM badges 
    INNER JOIN users_badges 
       ON badges.id = users_badges.badge_id 
    INNER JOIN users 
       ON users_badges.user_id = users.id 
    INNER JOIN games AS gamesBefore 
       ON users.id = game.user_id 
       AND gamesBefore.created <= users_badges.created 
WHERE users.id = 1 
GROUP BY user.id, badge.id 

那么一点点解释的 - 你需要选择所有可能的计数的用户X徽章 - 所以我们按自己的ID和计数之前有多少游戏。正如我之前所做的那样 - 根据您的要求,您不需要两次参加游戏。

+0

太棒了!正是我在找什么。谢谢。 – louisroy