Mysql 通过与其他表(表差异)进行比较,将元素删除并添加到表中

Mysql 通过与其他表(表差异)进行比较,将元素删除并添加到表中,mysql,sql,stored-procedures,Mysql,Sql,Stored Procedures,我正在开发一个标签系统,我有一个表(贴子和标签之间的映射),其中包含以下列: post_id,tag_id 8,9 8,17 8,3 我有一个临时表,其中包含应该用于帖子的标签id(它只包含id列) 我想实现一个用户可以修改标记(添加/删除)的功能(基于SQL)-如果用户删除标记,我想知道要从第一个表中删除哪些ID,如果要添加新标记,我想知道应该将其添加到第一个表中 在下面的示例中,将从表中删除标记17,并添加标记66 我正在寻找创建这样一个SQL查询的助手。 谢谢大家! 以下是设置: CRE

我正在开发一个标签系统,我有一个表(贴子和标签之间的映射),其中包含以下列:

post_id,tag_id
8,9
8,17
8,3
我有一个临时表,其中包含应该用于帖子的标签id(它只包含id列)

我想实现一个用户可以修改标记(添加/删除)的功能(基于SQL)-如果用户删除标记,我想知道要从第一个表中删除哪些ID,如果要添加新标记,我想知道应该将其添加到第一个表中

在下面的示例中,将从表中删除标记17,并添加标记66

我正在寻找创建这样一个SQL查询的助手。 谢谢大家!

以下是设置:

CREATE TABLE mapping ( post_id INT, tag_id INT, PRIMARY KEY (post_id, tag_id));
INSERT INTO mapping VALUES (8,9),(8,17),(8,3);

CREATE TABLE temp_mapping (tag_id INT PRIMARY KEY);
INSERT INTO temp_mapping VALUES (9),(3),(66);
我们可以使用一种味道或另一种味道(左或右)的外部连接来查找两个方向上不匹配的值

我们可以使用这些来格式化新的SQL语句,然后可以使用PREPARE和EXECUTE执行这些语句以应用更改

SELECT CONCAT('DELETE FROM mapping WHERE post_id=8 AND tag_id IN (', GROUP_CONCAT(m.tag_id), ');') AS _sql
FROM mapping m 
LEFT OUTER JOIN temp_mapping t ON m.tag_id = t.tag_id
WHERE m.post_id = 8 AND t.tag_id IS NULL
UNION ALL
SELECT CONCAT('INSERT INTO mapping (post_id, tag_id) VALUES ', GROUP_CONCAT(CONCAT('(8, ', t.tag_id, ')')), ';')
FROM mapping m 
RIGHT OUTER JOIN temp_mapping t ON m.tag_id = t.tag_id AND m.post_id = 8 
WHERE m.tag_id IS NULL;
输出:

+---------------------------------------------------------+
| _sql                                                    |
+---------------------------------------------------------+
| DELETE FROM mapping WHERE post_id=8 AND tag_id IN (17); |
| INSERT INTO mapping (post_id, tag_id) VALUES (8, 66);   |
+---------------------------------------------------------+
以下是设置:

CREATE TABLE mapping ( post_id INT, tag_id INT, PRIMARY KEY (post_id, tag_id));
INSERT INTO mapping VALUES (8,9),(8,17),(8,3);

CREATE TABLE temp_mapping (tag_id INT PRIMARY KEY);
INSERT INTO temp_mapping VALUES (9),(3),(66);
我们可以使用一种味道或另一种味道(左或右)的外部连接来查找两个方向上不匹配的值

我们可以使用这些来格式化新的SQL语句,然后可以使用PREPARE和EXECUTE执行这些语句以应用更改

SELECT CONCAT('DELETE FROM mapping WHERE post_id=8 AND tag_id IN (', GROUP_CONCAT(m.tag_id), ');') AS _sql
FROM mapping m 
LEFT OUTER JOIN temp_mapping t ON m.tag_id = t.tag_id
WHERE m.post_id = 8 AND t.tag_id IS NULL
UNION ALL
SELECT CONCAT('INSERT INTO mapping (post_id, tag_id) VALUES ', GROUP_CONCAT(CONCAT('(8, ', t.tag_id, ')')), ';')
FROM mapping m 
RIGHT OUTER JOIN temp_mapping t ON m.tag_id = t.tag_id AND m.post_id = 8 
WHERE m.tag_id IS NULL;
输出:

+---------------------------------------------------------+
| _sql                                                    |
+---------------------------------------------------------+
| DELETE FROM mapping WHERE post_id=8 AND tag_id IN (17); |
| INSERT INTO mapping (post_id, tag_id) VALUES (8, 66);   |
+---------------------------------------------------------+

您可以通过向表1添加外键来实现这一点

Create table Table2 (id integer, PRIMARY KEY (id) )

Create table TABLE1 (postid integer, tagid integer
                     CONSTRAINT fk_ctagid FOREIGN KEY (tagid)
                     REFERENCES Table2(id)
                       ON DELETE CASCADE)
当从表2中删除标记ID时,也会从表1中删除标记ID


只有表2中的标记ID才会出现在表1中

您可以通过向表1添加外键来实现这一点

Create table Table2 (id integer, PRIMARY KEY (id) )

Create table TABLE1 (postid integer, tagid integer
                     CONSTRAINT fk_ctagid FOREIGN KEY (tagid)
                     REFERENCES Table2(id)
                       ON DELETE CASCADE)
当从表2中删除标记ID时,也会从表1中删除标记ID

只有表2中的标签ID才会出现在表1中