2010-10-02 4 views

Répondre

109

Tant que vous avez des index appropriés en place cela devrait fonctionner bien:

UPDATE table_a 
SET 
     column_a_1 = (SELECT table_b.column_b_1 
          FROM table_b 
          WHERE table_b.user_name = table_a.user_name) 
    , column_a_2 = (SELECT table_b.column_b_2 
          FROM table_b 
          WHERE table_b.user_name = table_a.user_name) 
WHERE 
    EXISTS (
     SELECT * 
     FROM table_b 
     WHERE table_b.user_name = table_a.user_name 
    ) 

UPDATE sqlite3 ne prend pas en charge une clause FROM, ce qui en fait un peu plus de travail que dans d'autres SGBDR.

Si les performances ne sont pas satisfaisantes, une autre option peut consister à créer de nouvelles lignes pour table_a à l'aide d'un select et à les joindre à table_a dans une table temporaire. Ensuite, supprimez les données de table_a et repeupler à partir du temporaire.

+4

je devais exclure la partie table_a de la gauche ha du côté de l'argument set, pour que cela fonctionne. En utilisant la réponse ci-dessus, cela ressemble à 'column_a_1 = (SELECT table_b.column_b_1 FROM table_b WHERE nom_utilisateur_table_table = table_a.user_name)' –

+0

Cette réponse aide à comprendre plus en détail comment copier pour une réponse postée sur http://stackoverflow.com/questions/17267417/comment-upsert-merge-insert-sur-duplicate-update-in-postgresql/17267423 # 17267423 – zerocog

+0

Combien de fois la jointure est effectuée ici? seulement 3 fois, ou plutôt 3 fois par ligne dans table_a? (mon SQL est rouillé) –

2

Il y a une même bien meilleure solution pour mettre à jour une table d'une autre table:

;WITH a AS 
(
    SELECT 
     song_id, 
     artist_id 
    FROM 
     online_performance 
) 
UPDATE record_performance 
SET 
    op_song_id=(SELECT song_id FROM a), 
    op_artist_id=(SELECT artist_id FROM a) 

; 
+1

Puisque ce qui précède recherche des lignes spécifiques (record_id = 2347), il faudrait écrire 1000 fois le code ci-dessus pour mettre à jour 1000 lignes? –

+0

Cela semble prometteur, mais cela ne fonctionnera pas si vous avez besoin de joindre les deux tables sur une colonne commune (comme 'user_name' dans la question d'origine). Au lieu de cela, toutes les valeurs correspondantes de la table en cours de mise à jour seront placées sur celles d'un seul enregistrement de la table source. J'ai essayé de répertorier la colonne commune et d'ajouter une condition "WHERE", mais cela n'a pas fonctionné. –

+0

** MISE À JOUR ** En fait, ma tentative était correcte. Je pourrais avoir eu une ligne supplémentaire dans la question et il a indiqué * aucune erreur * pour une raison quelconque, qui m'a confondu. La solution était en effet d'ajouter la colonne requise à la première sélection, puis de faire référence à toutes les autres sélections, par ex. '(SELECT song_id FROM un WHERE guid = record_performance.guid)' –

1

A partir de la version sqlite 3.15 la syntaxe pour UPDATE admet une colonne nom-liste dans la partie SET de sorte que le requête peut être écrite comme

UPDATE table_a 
SET 
    (column_a_1, column_a_2) = (SELECT table_b.column_b_1, table_b.column_b_2 
           FROM table_b 
           WHERE table_b.user_name = table_a.user_name) 
WHERE 
    EXISTS (
     SELECT * 
     FROM table_b 
     WHERE table_b.user_name = table_a.user_name 
    ) 

qui est non seulement plus court mais aussi plus rapide

Questions connexes