web-dev-qa-db-fra.com

Instruction UPDATE avec plusieurs jointures dans PostgreSQL

J'essaie de mettre à jour une table appelée incode_warrants et définissez le warn_docket_no à la viol_docket_no du incode_violations table.

J'ai la requête SQL suivante dans Postgres 9.3, mais quand elle se déclenche, j'obtiens l'erreur suivante:

Error : ERROR:  relation "iw" does not exist
LINE 1: update iw

Je suis plus une personne Active Record, donc mes compétences SQL brutes font gravement défaut. Je me demandais si quelqu'un pouvait m'aider à me diriger dans la bonne direction sur la façon de corriger cette requête.

update iw
set iw.warn_docket_no = iv.viol_docket_no
from incode_warrants as iw
INNER JOIN incode_warrantvs as iwvs
on iw.warn_rid = iwvs.warnv_rid
INNER JOIN incode_violations as iv
ON iv.viol_citation_no = iwvs.warnv_citation_no and iv.viol_viol_no = iwvs.warnv_viol_no
16
nulltek

Identique à l'instruction UPDATE valide dans Postgres:

UPDATE incode_warrants iw
SET    warn_docket_no = iv.viol_docket_no
FROM   incode_warrantvs  iwvs
JOIN   incode_violations iv ON iv.viol_citation_no = iwvs.warnv_citation_no
                           AND iv.viol_viol_no = iwvs.warnv_viol_no
WHERE  iw.warn_rid = iwvs.warnv_rid;

Vous ne pouvez pas simplement utiliser un alias de table dans la clause FROM comme table cible dans la clause UPDATE. La (une!) Table à mettre à jour vient juste après UPDATE. Vous pouvez y ajouter un alias si vous le souhaitez. C'est la cause immédiate de votre message d'erreur, mais il y a plus.

La colonne à mettre à jour provient toujours de la seule table à mettre à jour et ne peut pas être qualifiée de table.

Vous n'avez pas besoin de répéter la table cible dans la clause FROM.

Tout cela et plus dans l'excellent manuel.

45
Erwin Brandstetter

Votre requête devrait ressembler à ceci:

UPDATE incode_warrants
SET warn_docket_no = incode_violations.viol_docket_no
FROM incode_violations
WHERE incode_violations.viol_citation_no = incode_warrants.warnv_citation_no
AND incode_violations.viol_viol_no = incode_warrants.warnv_viol_no;

Vous n'avez besoin d'aucune autre jointure. Avec cette requête, vous mettez simplement à jour une colonne dans une table avec les valeurs d'une colonne d'une autre table. Bien sûr, il ne se met à jour que lorsque la condition WHERE est vraie.

5
Walerian Sobczak

Votre mise à jour d'une table, pas la jointure

update incode_warrants ALIAS
set warn_docket_no = iv.viol_docket_no
from incode_warrantvs as iw 
...
1