5

您好,我有 2 个表:user_badgesbadges表,以下是user_badges表数据:

id | user_id | badge_id | points_earned | badges_awarded |
 1    2324        0             5               0

如果用户满足最低要求点数,即badges表中的 5,SQL 将更新上述内容为:

id | user_id | badge_id | points_earned | badges_awarded |
 1    2324        1             5               1

如果将来为同一用户注册了新积分,则user_table徽章将添加一个新行,如下所示:

 id | user_id | badge_id | points_earned | badges_awarded |
  1    2324        1             5               1
  2    2324        0             7               0

上述问题已解决


这是badges表:

badge_id | badge_name | required_points
   1           new          5
   2           adv          10

下面是我需要的


问题是我需要一个查询来将user_badges表与badges表进行比较,前提是查询必须知道之前是否已授予徽章。

我将其用于 Zend 应用程序,需要解决此问题的方法...

4

3 回答 3

5

如果我正确理解您的问题,首先您需要获取之前尚未授予徽章的用户,然后使用correlated subquery您需要更新表格,并从表格中user_badges获得相应的最高有效值。badges_idbadges

UPDATE user_badges a
       INNER JOIN(SELECT DISTINCT user_id, SUM(badges_awarded) AS total_badges_awarded
                  FROM user_badges
                  GROUP BY user_id
                 ) b
             ON a.user_id = b.user_id
                AND b.total_badges_awarded = 0
SET a.badge_id = (@var_badges_awarded_flag:= (IFNULL((
                             SELECT c.badge_id
                             FROM badges c
                             WHERE a.points_earned > c.required_points
                             ORDER BY c.required_points DESC
                             LIMIT 1
                            ), 0))),
    a.badges_awarded = a.badges_awarded + IF(@var_badges_awarded_flag > 0, 1, 0);
于 2012-08-20T07:36:33.793 回答
0

我不会跟踪在user_badges表中获得的积分,而是将它们保存在其他地方,要么在users表内,要么在单独的表中user_points。这使得只需一个简单的UPDATE ... SET earned_points = earned_points + :points.

接下来,我会将user_badges表格简化为:

user_id | badge_id

使用跨越UNIQUE索引来确保用户不能拥有多个徽章。

最后,更新user_badges表可以通过两个步骤作为后台任务(cron 等)执行:

  1. 确定使用 获得了哪些徽章points_earned >= required_points
  2. 将新徽章插入user_badgesusing INSERT IGNORE INTO user_badges ...; 这样可以确保只添加新的徽章并且不会覆盖现有的徽章。
于 2012-08-22T06:04:48.757 回答
0

下面是一些 SQL 逻辑,可以让您获得所有用户以及每个人可以获得的下一个徽章:

SELECT *
FROM user_badges
JOIN badges
ON badges.badge_id = (user_badges.badge_id + 1)

然后您可以遍历每个用户并确定他们的徽章是否需要使用 PHP 更新:

while ($row = mysqli_fetch_assoc($result)) // where result is the result from running the above query
{
    if ($row["points_earned"] >= $row["required_points"]) // enough points for next badge, update badges
    {
        mysqli_query("UPDATE user_badges SET badge_id = badge_id + 1, badges_awarded = badges_awarded + 1 WHERE user_id = ".$row['user_id']);
    }
}

这只是一些帮助您入门的示例 SQL/PHP 代码。您可以查询所需的任何行,在 PHP 中检查它们,并在需要时随时更新它们。

于 2012-08-14T05:31:32.873 回答