2013-09-21 51 views
10

Muszę aktualizować wiele kolumn w wielu wierszach w PostgreSQL 9.1. Jestem obecnie robi to z wielu różnych UPDATE zapytań, każdy, który działa na innym wierszu (w oparciu o klucz podstawowy):Aktualizowanie wielu wierszy z innym kluczem podstawowym w jednym zapytaniu w 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; 

muszę zrobić kilka tysięcy tych zapytań.

Czy mimo to mogę "zbiorczo aktualizować" wiele wierszy w jednym zapytaniu w PostgreSQL? Jeśli używasz INSERT, możesz wstawić wiele wierszy naraz: (INSERT INTO mytable (column_a, column_b) VALUES ((12, 6), (1, 45));), Czy jest coś takiego dla UPDATE?

Coś jak:

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

??

Ważne jest to, że każda "WARTOŚĆ" aktualizuje tylko jeden wiersz (na podstawie WHERE id =). Każdy wiersz będzie miał taką samą, stałą liczbę kolumn, które wymagają aktualizacji, ale każdy wiersz będzie miał różne wartości dla każdej kolumny, więc UPDATE mytable SET column_a = 12, column_b = 6 WHERE id IN (1, 2, 3); nie będzie działać.

Odpowiedz

7

Jeśli dotyczy to Twojego przypadku, możesz z niego skorzystać.

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

Tak, można (i zwykle jest to korzystne w SQL), aby zaktualizować kilka wierszy naraz. Są tam kilka sposobów, aby to zrobić, ale najbardziej czytelny i elegancki myślę jest użycie tabeli pochodzący z identyfikatorów i wartości:

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 

nie tak czytelny, ale bardziej oczywistym rozwiązaniem byłoby wykorzystanie case:

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

To podejście sprawdziło się doskonale! Dzięki!! Działa również z łączeniem na wielu kluczach/kolumnach. To znaczy "gdzie c.id = m.id AND c.column_a = m.column_a"; –