MySQL 查询,插入时出现重复问题

MySQL Query, problems with with duplicates on insert into

所以我正在使用论坛软件 Xenforo,我需要有关 SQL 查询的帮助,该查询将定期执行。该论坛将拥有大约 300-500 名活跃用户。所以没什么太大的。

目标:

所有用户 xf_users 都需要订阅 node_id 71,但属于某些 user_group_id 的用户除外。

现在用户可以取消订阅论坛或更改 notify_onsend_alert & send_email 字段。我不要那个。所以如果用户 'unsubscribe' 需要重新添加。

唯一接受的更改是 notify_on 也可以是“消息”。

总结:

到目前为止我得到了什么:

我的想法#1 是一个导火索。问题是,我从来没有写过触发器,也不知道如何解决我的问题。

想法 #2 是在 phpMyAdmin 中编写一个“事件”,它会定期运行查询。

我得到了将所有正确用户插入列表一次的代码,但我在保持列表更新方面遇到了问题。

我已经尝试使用 ON DUPLICATE KEY UPDATE...但我没有让它按预期工作。

我的快速解决方案是删除 node_id 71 的所有行并使用下面的查询重新添加所有行,但这不允许用户 select notify_on “消息”。还有

帮忙? ♥

table:

Screenshot of the table

(!! table 还将包含不同的行 node_id。这些必须保持不变!!)

代码:

insert into xf_forum_watch
    select user_id,
    "71" as node_id,
    "thread" as notify_on,
    "1" as send_alert,
    "1" as send_email
    from xf_user
where user_group_id NOT IN (1, 18, 40);

这会将正确的用户添加到列表中(见屏幕截图)。但是,如果用户已经订阅,它会抛出错误。


希望我没有遗漏任何细节。如果还有问题,请告诉我。

感谢各种帮助。

PS:我希望我没有破坏格式。我不习惯在这里发帖。


编辑:感谢@GMB 的解决方案。

我有一个后续问题。我想将工作查询放入存储过程,但它给了我一个错误:

DELIMITER $$

CREATE PROCEDURE forceSubscribeToNode(
    IN node_id_var INT
)
BEGIN
    insert into xf_forum_watch
    (user_id, node_id, notify_on, send_alert, send_email)
    select user_id,
    node_id_var as node_id,
    "thread" as notify_on,
    1 as send_alert,
    1 as send_email
    from xf_user
where user_group_id NOT IN (1, 18, 40)
on duplicate key update 
    send_alert = 1,
    send_email = 1,
    notify_on = case when notify_on is null or notify_on = '' then 'thread' else notify_on end
END $$

DELIMITER ;

错误:

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'END' at line 18

(第 18 行是“send_email = 1,”)

我做错了什么?

您只需在查询中添加 on duplicate key

insert into xf_forum_watch
    (user_id, node_id, notify_on, send_alert, send_email)
    select user_id,
    71 as node_id,
    'thread' as on notify_on,
    1 as send_alert,
    1 as send_email
    from xf_user
where user_group_id NOT IN (1, 18, 40)
on duplicate key update 
    send_alert = 1,
    send_email = 1,
    notify_on = 'thread'

这假设您设置了正确的主键唯一性,以便正确识别重复项。

如果你想在 on duplicate key 子句中使用条件逻辑,那也是可能的:

on duplicate key update 
    send_alert = case when send_alert = 0 then 1 else send_alert end,
    send_email = case when send_email = 0 then 1 else send_email end,
    notify_on = case when notify_on is null or notify_on = '' then  'thread' else notify_on end