2013-09-21 12 views
10

Ich muss viele Spalten in vielen Zeilen in PostgreSQL 9.1 aktualisieren. Ich mache es zur Zeit mit vielen verschiedenen UPDATE Anfragen, von denen jeder, der auf einer anderen Zeile (basierend auf dem Primärschlüssel) funktioniert:Aktualisieren mehrerer Zeilen mit unterschiedlichen Primärschlüssel in einer Abfrage in PostgreSQL?

UPDATE mytable SET column_a = 12, column_b = 6 WHERE id = 1; 
UPDATE mytable SET column_a = 1, column_b = 45 WHERE id = 2; 
UPDATE mytable SET column_a = 56, column_b = 3 WHERE id = 3; 

ich mehrere tausend dieser Abfragen zu tun haben.

Gibt es sowieso ich kann viele Zeilen in einer Abfrage in PostgreSQL "Bulk-update"? Wenn Sie INSERT verwenden, können Sie mehrere Zeilen gleichzeitig einfügen: (INSERT INTO mytable (column_a, column_b) VALUES ((12, 6), (1, 45));), Gibt es so etwas für UPDATE?

Etwas wie:

UPDATE mytable SET (id, column_a, column_b) FROM VALUES ((1, 12, 6), (2, 1, 45), (3, 56, 3), …) 

??

Wichtig ist, dass jeder 'VALUE' nur eine Zeile aktualisiert (basierend auf WHERE id =). Jede Zeile hat die gleiche feste Anzahl von Spalten, die aktualisiert werden müssen, aber jede Zeile hat andere Werte für jede Spalte, so dass UPDATE mytable SET column_a = 12, column_b = 6 WHERE id IN (1, 2, 3); nicht funktioniert.

Antwort

7

Wenn dies für Ihren Fall anwendbar ist, können Sie es verwenden.

create table test(id int, a int, b int); 

insert into test(id, a, b) 
values 
(1, 1, 1), 
(2, 1, 1), 
(3, 1, 1), 
(4, 1, 1), 
(5, 1, 1), 
(6, 1, 1), 
(7, 1, 1); 


update test as d 
set a = s.a, b = s.b 
from 
(
    values 
    (1, 2, 2), 
    (2, 2, 2) 
) as s(id, a, b) 
where d.id = s.id 

SQL FIDDLE DEMO

16

Ja, Sie können (und in der Regel ist es in SQL bevorzugt), um mehrere Zeilen zu aktualisieren. Im moment gibt es ein paar Möglichkeiten, dies zu tun, aber die meisten lesbar und elegant ich denke, ist eine abgeleitete Tabelle zu verwenden, um mit ids und Werte:

update mytable as m set 
    column_a = c.column_a, 
    column_b = c.column_b 
from (values 
    (1, 12, 6), 
    (2, 1, 45), 
    (3, 56, 3) 
) as c(id, column_a, column_b) 
where c.id = m.id 

nicht so lesbar, aber offensichtliche Lösung wäre case zu verwenden:

update mytable set 
    column_a = case id when 1 then 12 when 2 then 1 when 3 then 56 end, 
    column_b = case id when 1 then 6 when 2 then 45 when 3 then 3 end 
where id in (1, 2, 3) 
+0

Dieser Ansatz hat gut für mich gearbeitet !! Vielen Dank!! Funktioniert auch mit dem Verbinden mehrerer Schlüssel/Spalten. Das heißt, "wobei c.id = m.id UND c.column_a = m.column_a"; –