Je cherche à mettre à jour plusieurs lignes dans PostgreSQL en une seule déclaration. Y a-t-il un moyen de faire quelque chose comme ce qui suit?
UPDATE table
SET
column_a = 1 where column_b = '123',
column_a = 2 where column_b = '345'
Vous pouvez également utiliser la syntaxe update ... from
et utiliser une table de mappage. Si vous voulez mettre à jour plus d'une colonne, c'est beaucoup plus généralisable:
_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;
_
Vous pouvez ajouter autant de colonnes que vous le souhaitez:
_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;
_
Basé sur la solution de @Roman, vous pouvez définir plusieurs valeurs:
update users as u set -- postgres FTW
email = u2.email,
first_name = u2.first_name,
last_name = u2.last_name
from (values
(1, '[email protected]', 'Hollis', 'O\'Connell'),
(2, '[email protected]', 'Robert', 'Duncan')
) as u2(id, email, first_name, last_name)
where u2.id = u.id;
Oui, vous pouvez:
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')
Et preuve de travail: http://sqlfiddle.com/#!2/97c7ea/1
Pour mettre à jour plusieurs lignes en une seule requête, vous pouvez essayer ceci
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
si vous n'avez pas besoin de condition supplémentaire, supprimez and
partie de cette requête
Je suis tombé sur un scénario similaire et l'expression CASE m'a été utile.
UPDATE reports SET is_default =
case
when report_id = 123 then true
when report_id != 123 then false
end
WHERE account_id = 321;
Rapports - est une table ici, account_id est identique pour les report_ids mentionnés ci-dessus. La requête ci-dessus définira 1 enregistrement (celui qui correspond à la condition) sur true et tous les enregistrements non correspondants sur false.
Supposons que vous avez un tableau de ID et un tableau équivalent de statuts - voici un exemple comment procéder avec un SQL statique (une requête SQL qui ne change pas en raison de valeurs différentes) des tableaux:
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;