Je veux copier toutes les valeurs d'une colonne val1
d'une table table1
dans une colonne val2
d'une autre table table2
. J'ai essayé cette commande dans PostgreSQL:
update table2
set val2 = (select val1 from table1)
Mais j'ai eu cette erreur:
ERREUR: plusieurs lignes renvoyées par une sous-requête utilisée comme expression
Y a-t-il une alternative pour le faire?
Votre requête UPDATE
devrait ressembler à ceci:
UPDATE table2 t2
SET val2 = t1.val1
FROM table1 t1
WHERE t2.table2_id = t1.table2_id
AND t2.val2 IS DISTINCT FROM t1.val1 -- optional, to avoid empty updates
De la manière dont vous l'avez eu, il n'y avait pas de lien entre les lignes individuelles des deux tables. Chaque ligne serait extraite de table1
pour chaque ligne de table2
. Cela n'avait aucun sens (de manière onéreuse) et provoquait également une erreur de syntaxe, car une expression de sous-requête à cet endroit est uniquement autorisée à renvoyer une valeur unique.
J'ai résolu ce problème en joignant les deux tables sur table2_id
. Remplacez cela par tout ce qui relie réellement les deux.
J'ai réécrit la UPDATE
pour rejoindre table1
(avec la clause FROM
) au lieu d'exécuter des sous-requêtes corrélées, car elle est régulièrement plus rapide d'un ordre de grandeur.
Cela empêche également que table2.val2
soit annulé lorsqu'aucune ligne correspondante n'est trouvée dans table1
. Au lieu de cela, rien arrive à de telles lignes avec cette forme de la requête.
Vous pouvez inclure tous les mêmes éléments dans la liste FROM
que vous pourriez inclure dans un SELECT
simple (par exemple, plusieurs tables ou sous-requêtes). Par documentation:
from_listUne liste d'expressions de table, permettant aux colonnes d'autres tables de apparaissent dans la condition
WHERE
et les expressions de mise à jour. C'est similaire à la liste des tables pouvant être spécifiées dans la clauseFROM
d'une déclarationSELECT
. Notez que la table cible ne doit pas apparaître dans le from_list, sauf si vous envisagez une auto-jointure (auquel cas, il doit apparaître avec un alias dans le from_list).
WHERE
empêche les mises à jour qui ne changeraient rien - ce qui est pratiquement toujours une bonne idée (coût total, mais pas de gain - des exceptions exotiques s'appliquent).update table1 set table1_column = table2.column à partir de table2 table2 où id_table1 = table2.id