首页 > 解决方案 > UPDATE JOIN 表,数学运算仅发生在单个(最后?)行上

问题描述

在我的应用程序中,我跟踪用户的未读通知总数以及用户表中的其他用户数据。通知在单独的表中,类似性质的通知堆叠成一行,每行跟踪计数和最后一个时间戳。现在我想实现一个功能,将所有通知标记为已读,直到特定时间戳。我使用来自两个不同表的两列之间的数学减法进行了此查询:

        UPDATE 
            core_notification n
        LEFT JOIN 
            core_user u
        ON 
            n.notification__user_id = u.user__id
        SET
            n.notification__if_read = 1,
            u.user__notification_unread_count = u.user__notification_unread_count - n.notification__main_count
        WHERE
            n.notification__timestamp <= 123456 AND
            n.notification__if_read = 0 AND
            n.notification__user_id = 123;

问题:假设在用户表中“user__notification_unread_count”的值为 4,并且有两个通知的“notification__main_count”值为 2。运行此查询并将两个通知更新为已读后我的目标是具有“user__notification_unread_count”值0 (4 - 2 - 2 = 0)。但是结果总是 2。我尝试了各种连接方法,但似乎这正是数据库在更新多行时的工作方式(每个更新的行都会完全覆盖以前的更新,但这只是我的假设)。有没有一种方法可以通过单个查询实现我想要的结果?

标签: mysqlsql

解决方案


在这种情况下,您可能最好使用触发器。但 。. . 您可以在一次更新中完成,只需做更多工作:

UPDATE core_notification n LEFT JOIN 
       core_user u
       ON n.notification__user_id = u.user__id LEFT JOIN
       (SELECT n2.notification__user_id,
               SUM(n2.notification__main_count) as total_notification__main_count
        FROM core_notification n2
        WHERE n2.notification__timestamp <= 123456 AND
              n2.notification__if_read = 0 AND
              n2.notification__user_id = 123;
        GROUP BY n2.notification__user_id
       ) n2
       ON n2.notification__user_id = n2.notification__user_id
SET n.notification__if_read = 1,
    u.user__notification_unread_count = u.user__notification_unread_count - n2.total_notification__main_count
WHERE n.notification__timestamp <= 123456 AND
      n.notification__if_read = 0 AND
      n.notification__user_id = 123;

n2派生表单独计算需要减去的总数。


推荐阅读