如何在特定位置将值插入 Postgres DB 列数组?
How do I insert a value into a Postgres DB column array at a specific position?
CREATE TABLE array_test (
id serial primary key,
data text[]
);
INSERT INTO array_test (data) VALUES
('{"one", "two"}');
-- 现在我需要插入数组的第二个成员。我的尝试如下,但代码只重新定义了第二个成员:
UPDATE array_test SET data[2] = 'three'
WHERE id = 1;
我不记得允许你自动换档的数组函数,所以这里有一些编码:
t=# begin;
BEGIN
Time: 0.117 ms
t=# with idx(v,t) as (values(2,'three'))
t-# , u as (select case when o > v then o+1 else o end, e from array_test,idx,unnest(data) with ordinality u(e,o) where id =1)
t-# , f as (select * from u union select * from idx)
t-# , r as (select array_agg(e order by o) from f)
t-# update array_test set data = array_agg
t-# from r
t-# where id =1;
UPDATE 1
Time: 0.635 ms
t=# select * from array_test;
id | data
----+-----------------
1 | {one,two,three}
(1 row)
Time: 0.207 ms
t=# end;
COMMIT
Time: 0.874 ms
CTE idx(v,t) as (values(2,'three'))
是您的 [2]
和 three
- 它的价值
您可以对现有数组进行切片并将新值附加到这些切片:
update array_test
set data = data[:1]||'three'::text||data[2:];
data[:1]
选择第一个元素之前的所有内容,data[2:]
选择第二个元素之后(包括)之后的所有内容。
如果您经常需要它,将它放入一个函数中可能是有意义的。
create or replace function array_set_at(p_data text[], p_pos int, p_element text)
returns text[]
as
$$
select p_data[:p_pos - 1]||p_element||p_data[p_pos:];
$$
language sql;
那么你可以这样做:
update array_test
set data = array_set_at(data, 2, 'three');
CREATE TABLE array_test (
id serial primary key,
data text[]
);
INSERT INTO array_test (data) VALUES
('{"one", "two"}');
-- 现在我需要插入数组的第二个成员。我的尝试如下,但代码只重新定义了第二个成员:
UPDATE array_test SET data[2] = 'three'
WHERE id = 1;
我不记得允许你自动换档的数组函数,所以这里有一些编码:
t=# begin;
BEGIN
Time: 0.117 ms
t=# with idx(v,t) as (values(2,'three'))
t-# , u as (select case when o > v then o+1 else o end, e from array_test,idx,unnest(data) with ordinality u(e,o) where id =1)
t-# , f as (select * from u union select * from idx)
t-# , r as (select array_agg(e order by o) from f)
t-# update array_test set data = array_agg
t-# from r
t-# where id =1;
UPDATE 1
Time: 0.635 ms
t=# select * from array_test;
id | data
----+-----------------
1 | {one,two,three}
(1 row)
Time: 0.207 ms
t=# end;
COMMIT
Time: 0.874 ms
CTE idx(v,t) as (values(2,'three'))
是您的 [2]
和 three
- 它的价值
您可以对现有数组进行切片并将新值附加到这些切片:
update array_test
set data = data[:1]||'three'::text||data[2:];
data[:1]
选择第一个元素之前的所有内容,data[2:]
选择第二个元素之后(包括)之后的所有内容。
如果您经常需要它,将它放入一个函数中可能是有意义的。
create or replace function array_set_at(p_data text[], p_pos int, p_element text)
returns text[]
as
$$
select p_data[:p_pos - 1]||p_element||p_data[p_pos:];
$$
language sql;
那么你可以这样做:
update array_test
set data = array_set_at(data, 2, 'three');