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

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

Votre UPDATE la requête 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, see below

De la façon dont vous l'aviez, il n'y avait aucun lien entre les lignes individuelles des deux tables. Chaque ligne serait extraite de table1 pour chaque ligne de table2 . Cela n'avait aucun sens (d'une manière coûteuse) et a également déclenché l'erreur de syntaxe, car une expression de sous-requête à cet endroit n'est autorisée à renvoyer qu'une seule valeur.

J'ai corrigé cela en joignant les deux tables sur table2_id . Remplacez cela par tout ce qui relie réellement les deux.

J'ai réécrit le UPDATE pour rejoindre table1 (avec le FROM clause) au lieu d'exécuter des sous-requêtes corrélées, car cela est généralement plus rapide d'un ordre de grandeur.
Cela empêche également que table2.val2 serait annulé si aucune ligne correspondante n'est trouvée dans table1 . Au lieu de cela, rien arrive à de telles lignes avec cette forme de requête.

Vous pouvez ajouter des expressions de table au FROM liste comme le ferait dans un simple SELECT (tables, sous-requêtes, fonctions renvoyant des ensembles, ...). Le manuel :

from_list

Une liste d'expressions de table, permettant aux colonnes d'autres tables d'apparaître dans WHERE condition et les expressions de mise à jour. Ceci est similaire à la liste des tables qui peuvent être spécifiées dans le FROM Clause d'un SELECT déclaration. Notez que la table cible ne doit pas apparaître dans la from_list , sauf si vous avez l'intention d'effectuer une auto-jointure (auquel cas elle doit apparaître avec un alias dans la from_list ).

Le dernier WHERE La clause empêche les mises à jour qui ne changeraient rien - ce qui est pratiquement toujours une bonne idée (coût presque total mais aucun gain, des exceptions exotiques s'appliquent). S'il est garanti que l'ancienne et la nouvelle valeur sont NOT NULL , simplifier en :

AND   t2.val2 <> t1.val1
  • Comment puis-je (ou puis-je) SELECT DISTINCT sur plusieurs colonnes ?