これは、単一のSQLステートメントで実行できます。
INSERT INTO user_recipe
SELECT new_UserId, new_RecipeId
FROM user_recipe
WHERE NOT EXISTS (
SELECT *
FROM user_recipe
WHERE (UserId, RecipeId) = (new_UserId, new_RecipeId)
);
SELECT
行がまだ存在しない場合にのみ返されるため、この場合にのみ挿入されます。
バルクインサートのソリューション
一度に挿入するレシピのリストが長い場合は、次のことができます。
CREATE TEMP TABLE i(userId int, recipeid int) ON COMMIT DROP;
INSERT INTO i VALUES
(1,2), (2,4), (2,4), (2,7), (2,43), (23,113), (223,133);
INSERT INTO user_recipe
SELECT DISTINCT i.* -- remove dupes from the insert candidates themselves
FROM i
LEFT JOIN user_recipe u USING (userid, recipeid)
WHERE u.userid IS NULL;
一度に一握りを挿入するためのソリューション
マイクがコメントしたように、一時的なテーブルはほんの数レコードではやり過ぎでしょう。
INSERT INTO user_recipe
SELECT i.*
FROM (
SELECT DISTINCT * -- only if you need to remove possible dupes
FROM (
VALUES (1::int, 2::int)
,(2, 3)
,(2, 4)
,(2, 4) -- dupe will be removed
,(2, 43)
,(23, 113)
,(223, 133)
) i(userid, recipeid)
) i
LEFT JOIN user_recipe u USING (userid, recipeid)
WHERE u.userid IS NULL;