2010-10-02 6 views

risposta

109

Finché si dispone di indici adatti a posto questo dovrebbe funzionare bene:

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 in sqlite3 non supporta una clausola FROM, che rende questo un po 'di lavoro che in altri RDBMS.

Se le prestazioni non sono soddisfacenti, un'altra opzione potrebbe essere quella di creare nuove righe per table_a utilizzando un select e join con table_a in una tabella temporanea. Quindi elimina i dati da table_a e ripopola dal temporaneo.

+4

ho dovuto escludere la parte table_a dalla sinistra ha lato dell'argomento impostato, per farlo funzionare. Usando la risposta sopra, appare come 'column_a_1 = (SELECT table_b.column_b_1 FROM table_b WHERE table_b.user_name = table_a.user_name)' –

+0

Questa risposta aiuta a capire in modo più dettagliato come copiare per la risposta pubblicata su http://stackoverflow.com/questions/17267417/how-to-upsert-merge-insert-on-duplicate-update-in-postgresql/17267423 # 17267423 – zerocog

+0

Quante volte il join viene eseguito qui? solo 3 volte, o 3 volte per riga in table_a? (il mio SQL è arrugginito) –

2

C'è una soluzione ancora migliore per aggiornare una tabella da un'altra tabella:

;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

Poiché quanto sopra è la ricerca di righe specifiche (record_id = 2347), uno dovrebbe scrivere il codice sopra 1000 volte per aggiornare 1000 righe? –

+0

Questo sembra promettente, ma non funzionerà quando è necessario unire entrambe le tabelle su una colonna comune (come 'user_name' nella domanda originale). Invece, questo imposterà tutti i valori corrispondenti nella tabella che si aggiorna a quelli di un solo record nella tabella di origine. Ho provato ad elencare la colonna comune e ad aggiungere una condizione 'WHERE', ma non ha funzionato. –

+0

** AGGIORNAMENTO ** In realtà, il mio tentativo era corretto. Potrei aver avuto una riga in più nella query e ha detto * nessun errore * per qualche motivo, che mi ha confuso. La soluzione era infatti quella di aggiungere la colonna richiesta alla prima selezione, e quindi fare in modo che tutte le altre selezioni si riferissero ad essa, ad es. '(SELECT song_id FROM a WHERE guid = record_performance.guid)' –

1

A partire dalla versione SQLite 3.15 la sintassi per UPDATE ammette un nome-colonna-list nella parte SET in modo che il query può essere scritta come

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 
    ) 

che non è solo più breve ma anche più veloce

Problemi correlati