根据另一个表的值有条件地更新另一个表


Update one table conditionally based on values of another

嗨,我有 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应用程序,需要解决此问题...

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

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);

这里有一些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 中检查它们,并在必要时随时更新它们。

与其跟踪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. 使用 INSERT IGNORE INTO user_badges ... 将新徽章插入user_badges ; 这可确保仅添加新徽章,而不会覆盖现有徽章。