J'ai deux tables:
A [ID, column1, column2, column3]
B [ID, column1, column2, column3, column4]
A
sera toujours un sous-ensemble de B
(ce qui signifie que toutes les colonnes de A
sont également incluses B
).
Je souhaite mettre à jour un enregistrement avec un ID
in spécifique B
avec leurs données de A
pour toutes les colonnes de A
. Cela ID
existe à la fois dans A
et B
.
Existe-t-il une UPDATE
syntaxe ou tout autre moyen de le faire sans spécifier les noms de colonne, en disant simplement "définir toutes les colonnes de A" ?
J'utilise PostgreSQL, donc une commande non standard spécifique est également acceptée (mais pas préférée).
Réponses:
Vous pouvez utiliser la clause FROM non standard .
la source
La question est ancienne mais je sentais que la meilleure réponse n'avait pas encore été donnée.
Solution générale avec SQL dynamique
Vous n'avez pas besoin de connaître les noms de colonnes, à l'exception de certaines colonnes uniques à rejoindre (
id
dans l'exemple). Fonctionne de manière fiable pour tous les cas d'angle possibles auxquels je peux penser.Ceci est spécifique à PostgreSQL. Je construis du code dynamique basé sur le schéma_information , en particulier la table
information_schema.columns
, qui est définie dans la norme SQL et la plupart des grands SGBDR (sauf Oracle) l'ont. Mais uneDO
instruction avec du code PL / pgSQL exécutant du SQL dynamique est une syntaxe PostgreSQL totalement non standard.En supposant une colonne correspondante
b
pour chaque colonne dea
, mais pas l'inverse.b
peut avoir des colonnes supplémentaires.WHERE b.id = 123
est facultatif, pour mettre à jour une ligne sélectionnée.SQL Fiddle.
Réponses connexes avec plus d'explications:
Solutions partielles avec SQL brut
Avec liste des colonnes partagées
Vous devez toujours connaître la liste des noms de colonnes que les deux tables partagent. Avec un raccourci de syntaxe pour mettre à jour plusieurs colonnes - plus court que ce que les autres réponses suggèrent jusqu'à présent dans tous les cas.
SQL Fiddle.
Cette syntaxe a été introduite avec Postgres 8.2 en 2006, bien avant que la question ne soit posée. Détails dans le manuel.
En relation:
Avec la liste des colonnes dans
B
Si toutes les colonnes de
A
sont définiesNOT NULL
(mais pas nécessairementB
),et que vous connaissez les noms de colonnes de
B
(mais pas nécessairementA
).Le
NATURAL LEFT JOIN
joint une ligne à partir deb
laquelle toutes les colonnes du même nom contiennent les mêmes valeurs. Nous n'avons pas besoin d'une mise à jour dans ce cas (rien ne change) et pouvons éliminer ces lignes au début du processus (WHERE b.id IS NULL
).Nous devons encore trouver une ligne correspondante, donc
b.id = ab.id
dans la requête externe.db <> violon ici
Ancien sqlfiddle.
Il s'agit du SQL standard à l' exception de la
FROM
clause .Cela fonctionne quelle que soit la colonne réellement présente dans
A
, mais la requête ne peut pas faire la distinction entre les valeurs NULL réelles et les colonnes manquantes dansA
, elle n'est donc fiable que si toutes les colonnes deA
sont définiesNOT NULL
.Il existe plusieurs variantes possibles, en fonction de ce que vous savez sur les deux tables.
la source
SET (column1) = (a.column)
) Postgres le traitera comme un autre type de mise à jour et donnera une erreur comme ceci:source for a multiple-column UPDATE item must be a sub-SELECT or ROW() expression
Je travaille avec la base de données IBM DB2 depuis plus de dix ans et j'essaie maintenant d'apprendre PostgreSQL.
Il fonctionne sur PostgreSQL 9.3.4, mais ne fonctionne pas sur DB2 10.5:
Remarque: Le problème principal est une cause FROM qui n'est pas prise en charge dans DB2 et pas non plus dans ANSI SQL.
Cela fonctionne sur DB2 10.5, mais ne fonctionne PAS sur PostgreSQL 9.3.4:
ENFIN! Il fonctionne à la fois sur PostgreSQL 9.3.4 et DB2 10.5:
la source
B
, la première instruction ne fait rien (la ligne d'origine reste inchangée), tandis que les deux autres écrasent les colonnes avec des valeurs NULL.C'est une aide précieuse. Le code
fonctionne parfaitement.
a noté que vous avez besoin d'un crochet "" dans
pour le faire fonctionner.
la source
Pas nécessairement ce que vous avez demandé, mais peut-être que l'utilisation de l'héritage postgres pourrait vous aider?
Cela évite d'avoir à mettre à jour B.
Mais assurez-vous de lire tous les détails .
Sinon, ce que vous demandez n'est pas considéré comme une bonne pratique - les éléments dynamiques tels que les vues avec
SELECT * ...
sont déconseillés (car une telle commodité peut casser plus de choses que les choses d'aide), et ce que vous demandez serait équivalent pour laUPDATE ... SET
commande.la source
vous pouvez créer et exécuter SQL dynamique pour ce faire, mais ce n'est vraiment pas idéal
la source
Essayez de suivre
EDITED: - Mettre à jour plus d'une colonne
la source
UPDATE
MySQL , mais elle n'est pas valide pour PostgreSQL.