Bir ifadede PostgreSQL birden çok satır güncellemek için arıyorum. Aşağıdaki gibi bir şey yapmanın bir yolu var mı?
UPDATE table
SET
column_a = 1 where column_b = '123',
column_a = 2 where column_b = '345'
Bir ifadede PostgreSQL birden çok satır güncellemek için arıyorum. Aşağıdaki gibi bir şey yapmanın bir yolu var mı?
UPDATE table
SET
column_a = 1 where column_b = '123',
column_a = 2 where column_b = '345'
Yanıtlar:
Ayrıca kullanabilirsiniz update ... from
sözdizimi ve bir eşleme tablosu kullanabilirsiniz. Birden fazla sütunu güncellemek istiyorsanız, çok daha genelleştirilebilir:
update test as t set
column_a = c.column_a
from (values
('123', 1),
('345', 2)
) as c(column_b, column_a)
where c.column_b = t.column_b;
İstediğiniz kadar sütun ekleyebilirsiniz:
update test as t set
column_a = c.column_a,
column_c = c.column_c
from (values
('123', 1, '---'),
('345', 2, '+++')
) as c(column_b, column_a, column_c)
where c.column_b = t.column_b;
... from (values ('2014-07-21'::timestamp, 1), ('2014-07-20', 2), ...
@Roman'ın çözümüne dayanarak, birden fazla değer ayarlayabilirsiniz:
update users as u set -- postgres FTW
email = u2.email,
first_name = u2.first_name,
last_name = u2.last_name
from (values
(1, 'hollis@weimann.biz', 'Hollis', 'O\'Connell'),
(2, 'robert@duncan.info', 'Robert', 'Duncan')
) as u2(id, email, first_name, last_name)
where u2.id = u.id;
from (values $1)
$ 1 bir yapı dizisidir. Yukarıdaki durumda, katı özellik olarak id, first_name ve last_name olur.
Evet yapabilirsin:
UPDATE foobar SET column_a = CASE
WHEN column_b = '123' THEN 1
WHEN column_b = '345' THEN 2
END
WHERE column_b IN ('123','345')
Ve çalışma kanıtı: http://sqlfiddle.com/#!2/97c7ea/1
'123'
ne de '345'
. Kullanmalısınız WHERE column_b IN ('123','456')
...
'456'
olması gerekiyor'345'
ELSE column_b
Son WHEN ? THEN ?
satırdan sonra eklerseniz , sütun geçerli değerine ayarlanır ve böylece MatheusQI'nin söylediklerini önler.
Benzer bir senaryoya rastladı ve CASE ifadesi benim için yararlı oldu.
UPDATE reports SET is_default =
case
when report_id = 123 then true
when report_id != 123 then false
end
WHERE account_id = 321;
Raporlar - buradaki bir tablodur; account_id, yukarıda belirtilen report_ids için aynıdır. Yukarıdaki sorgu 1 kaydı (koşulla eşleşen kayıt) true olarak ve eşleşmeyen tüm kayıtları false olarak ayarlar.
Tek bir sorguda birden çok satırı güncellemek için bunu deneyebilirsiniz
UPDATE table_name
SET
column_1 = CASE WHEN any_column = value and any_column = value THEN column_1_value end,
column_2 = CASE WHEN any_column = value and any_column = value THEN column_2_value end,
column_3 = CASE WHEN any_column = value and any_column = value THEN column_3_value end,
.
.
.
column_n = CASE WHEN any_column = value and any_column = value THEN column_n_value end
ek koşula ihtiyacınız yoksa and
bu sorgunun bir kısmını kaldırın
Diyelim ki bir dizi kimliğiniz ve eşdeğer bir durum diziniz var - burada dizilerin statik bir SQL (farklı değerler nedeniyle değişmeyen bir sql sorgusu) ile nasıl yapılacağına bir örnek:
drop table if exists results_dummy;
create table results_dummy (id int, status text, created_at timestamp default now(), updated_at timestamp default now());
-- populate table with dummy rows
insert into results_dummy
(id, status)
select unnest(array[1,2,3,4,5]::int[]) as id, unnest(array['a','b','c','d','e']::text[]) as status;
select * from results_dummy;
-- THE update of multiple rows with/by different values
update results_dummy as rd
set status=new.status, updated_at=now()
from (select unnest(array[1,2,5]::int[]) as id,unnest(array['a`','b`','e`']::text[]) as status) as new
where rd.id=new.id;
select * from results_dummy;
-- in code using **IDs** as first bind variable and **statuses** as the second bind variable:
update results_dummy as rd
set status=new.status, updated_at=now()
from (select unnest(:1::int[]) as id,unnest(:2::text[]) as status) as new
where rd.id=new.id;