你可以做的两件事都会有所帮助。
首先按照 Devart 的建议向表中添加唯一索引/键。
第二件事是,这是一个很好的地方,您可以使用右连接和左连接来获取不存在的数据。我将向您展示该理论,然后您可以将其应用于您的答案作为练习。
步骤1:
创建一个名为 test 的数据库。
第2步:
在新创建的测试数据库中运行以下两个创建表脚本:
CREATE TABLE `test`.`category_has_manufacturer_A`
(
`id_category` INT NOT NULL ,
`id_manufacturer` INT NOT NULL ,
PRIMARY KEY (
`id_category`,
`id_manufacturer`
)
);
CREATE TABLE `test`.`category_has_manufacturer_B`
(
`id_category` INT NOT NULL ,
`id_manufacturer` INT NOT NULL ,
PRIMARY KEY (
`id_category`,
`id_manufacturer`
)
);
对,所以我们两个表有一个共同的列,我们可以加入。
第 3 步:
向 category_has_manufacturer_a 表添加一些数据
INSERT INTO `test`.`category_has_manufacturer_a`
(
`id_category`,
`id_manufacturer`
)
VALUES
(
1,
1
);
很酷,所以表 A有一些我们想要添加到表 B中的数据。
第4步:
让我们对这两个表进行内部连接,然后查看运行以下查询的结果。
SELECT
A.`id_category` AS A_ID_CATEGORY,
A.`id_manufacturer` AS A_ID_MANAFACTURER,
B.`id_category` AS B_ID_CATEGORY,
B.`id_manufacturer` AS B_ID_MANAFACTURER
FROM category_has_manufacturer_a A
INNER JOIN category_has_manufacturer_b B
ON A.`id_category` =B.`id_category`
AND A.`id_manufacturer`=B.`id_manufacturer`
太好了,因此没有返回数据,因为表 A和表 B中的行之间没有直接匹配,这是因为内部连接只返回与 JOIN 条件匹配的行。
第 5 步:
OUTER JOINS 的力量显露出来。即使它们不匹配,OUTER 连接也会返回数据。在这种情况下,我们将对表 A和表 B执行 LEFT OUTER JOIN 。由于表 A是LEFT表,我们要求返回表 A中的所有数据,即使它们与表 B中的任何内容都不匹配。运行以下查询。
SELECT
A.`id_category` AS A_ID_CATEGORY,
A.`id_manufacturer` AS A_ID_MANAFACTURER,
B.`id_category` AS B_ID_CATEGORY,
B.`id_manufacturer` AS B_ID_MANAFACTURER
FROM category_has_manufacturer_a A
LEFT OUTER JOIN category_has_manufacturer_b B
ON A.`id_category` =B.`id_category`
AND A.`id_manufacturer`=B.`id_manufacturer`
这将返回一个如下所示的记录集:
A_ID_CATEGORY|A_ID_MANAFACTURER|B_ID_CATEGORY|B_ID_MANAFACTURER|
1| 1| | |
该结果清楚地表明,表 A中的行与表 B中的行不匹配。
第 6 步:
现在我们可以使用步骤 5 中的 SELECT 语句创建一个 INSERT 语句来插入这些不存在的行。运行以下查询:
INSERT INTO category_has_manufacturer_b
SELECT
A.`id_category` AS A_ID_CATEGORY,
A.`id_manufacturer` AS A_ID_MANAFACTURER
FROM category_has_manufacturer_a A
LEFT OUTER JOIN category_has_manufacturer_b B
ON A.`id_category` =B.`id_category`
AND A.`id_manufacturer`=B.`id_manufacturer`
让我们检查插入运行以下查询的内容:
SELECT
`category_has_manufacturer_b`.`id_category`,
`category_has_manufacturer_b`.`id_manufacturer`
FROM `test`.`category_has_manufacturer_b`;
您将看到一个结果集,其中表 A中的行现在插入到表 B中。
第 7 步:
在这里,我们添加最后一点和部分,我们确保只将新行从表 A添加到表 B。首先让我们添加更多数据。运行以下查询:
INSERT INTO `test`.`category_has_manufacturer_a`
(
`id_category`,
`id_manufacturer`
)
VALUES
(
1,
2
);
现在再次使用左连接运行查询:
SELECT
A.`id_category` AS A_ID_CATEGORY,
A.`id_manufacturer` AS A_ID_MANAFACTURER,
B.`id_category` AS B_ID_CATEGORY,
B.`id_manufacturer` AS B_ID_MANAFACTURER
FROM category_has_manufacturer_a A
LEFT OUTER JOIN category_has_manufacturer_b B
ON A.`id_category` =B.`id_category`
AND A.`id_manufacturer`=B.`id_manufacturer`
您将看到一个结果集,其中包含两个表中匹配的行和表 a 中的新行。如果您现在运行插入,您将插入两行并且有主键冲突或者在您的情况下是重复行。
如果您将上面的查询更改为以下内容并运行它:
SELECT
A.`id_category` AS A_ID_CATEGORY,
A.`id_manufacturer` AS A_ID_MANAFACTURER,
B.`id_category` AS B_ID_CATEGORY,
B.`id_manufacturer` AS B_ID_MANAFACTURER
FROM category_has_manufacturer_a A
LEFT OUTER JOIN category_has_manufacturer_b B
ON A.`id_category` =B.`id_category`
AND A.`id_manufacturer`=B.`id_manufacturer`
WHERE B.`id_category` IS NULL AND B.`id_manufacturer` IS NULL
记录集将仅包含表 A中的新记录。
将插入语句更改为:
INSERT INTO category_has_manufacturer_b
SELECT
A.`id_category` AS A_ID_CATEGORY,
A.`id_manufacturer` AS A_ID_MANAFACTURER,
B.`id_category` AS B_ID_CATEGORY,
B.`id_manufacturer` AS B_ID_MANAFACTURER
FROM category_has_manufacturer_a A
LEFT OUTER JOIN category_has_manufacturer_b B
ON A.`id_category` =B.`id_category`
AND A.`id_manufacturer`=B.`id_manufacturer`
WHERE B.`id_category` IS NULL AND B.`id_manufacturer` IS NULL
当您运行此 INSERT 时,它只会将表 A中的新行插入到表 B中。
摘要: LEFT 和 RIGHT JOIN 语句可用于对两张表进行比较,并仅返回一张中的新行。如果行是新的,则在尝试从一个表添加到另一个表时,这是一项很棒的技术。它将同时在一行和多行上工作,并且由于它是基于设置的(SQL 擅长于此),因此速度非常快。
我希望您了解正在发生的事情并可以将其应用到您的触发器中。
提示: 在触发器中,您可以访问新表,您可以加入该表以确定新行。
玩得开心!