両方を実行できる2つのことが役立ちます。
Devartが提案したように、最初に一意のインデックス/キーをテーブルに追加します。
2つ目は、これは、右結合と左結合を使用して、存在しないデータを取得できる優れた場所であるということです。私はあなたに理論を示すつもりです、そしてあなたはそれを練習としてあなたの答えに適用することができます。
ステップ1:
testというデータベースを作成します。
ステップ2:
新しく作成されたテストデータベースで、次の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`
)
);
そのため、結合できる共通の列を持つ2つのテーブルがあります。
ステップ3:
category_has_manufacturer_aテーブルにデータを追加します
INSERT INTO `test`.`category_has_manufacturer_a`
(
`id_category`,
`id_manufacturer`
)
VALUES
(
1,
1
);
かっこいいので、テーブルAには、テーブルBに追加したいデータがいくつかあります。
ステップ4:
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
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:
OUTERJOINSのパワーが明らかになりました。OUTER結合は、一致しない場合でもデータを返します。この場合、テーブルAとテーブルBでLEFTOUTERJOINを実行します。表Aは左側のテーブルであるため、表Bのいずれとも一致しない場合でも、表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`
これにより、次のようなレコードセットが返されます。
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`
両方のテーブルで一致する行と、テーブルのみの新しい行を含む結果セットが表示されます。ここで挿入を実行すると、両方の行が挿入され、主キー違反が発生するか、場合によっては行が重複します。
上記のクエリを次のように変更して実行すると、次のようになります。
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ステートメントを使用して、2つのテーブルを比較し、1つから新しい行のみを返すことができます。これは、行が新しい場合に1つのテーブルから別のテーブルに追加しようとするときに優れた手法です。1行と複数行で同時に動作し、セットベースであるため(SQLはこれに優れています)、超高速です。
何が起こっているのかを理解し、これをトリガーに適用できることを願っています。
ヒント: トリガーでは、NEWテーブルにアクセスでき、これに参加して新しい行を決定できます。
楽しむ!