web-dev-qa-db-fra.com

Mettre à jour une colonne d'une table avec une colonne d'une autre table dans PostgreSQL

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?

22
f.ashouri

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_list

Une 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 clause FROM d'une déclaration SELECT. 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).

  • La dernière clause 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).
52
Erwin Brandstetter

update table1 set table1_column = table2.column à partir de table2 table2 où id_table1 = table2.id 

  1. n'utilisez pas le nom d'alias pour table1.
  2. les tables sont table1, table2 
0
Bharath Pateru