PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Approche recommandée pour insérer de nombreuses lignes avec Castle ActiveRecord et ignorer les doublons

Vous pouvez le faire avec une seule instruction 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)
   );

Le SELECT ne renvoie la ligne que si elle n'existe pas déjà, elle ne sera donc insérée que dans ce cas.

Solution pour les insertions en vrac

Si vous avez une longue liste de recettes à insérer en une fois, vous pouvez :

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;

Solution pour insérer une poignée à la fois

Une table temporaire serait exagérée pour quelques enregistrements seulement, comme l'a commenté Mike.

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;