postgres — агрегировать элементы в текстовом массиве

#sql #arrays #string #postgresql #csv

#sql #массивы #строка #postgresql #csv

Вопрос:

У меня есть массив текстовых элементов, каждый текстовый элемент в массиве представляет собой строку с разделителями, вот пример:

 drop table if exists tmp;
create table tmp(x text);
insert into tmp select ('1~41.5~50~1|2~43.72~1000~1|3~52.0~1~1|4~57.5~7500~1|5~68.0~8~1|6~80.95~6~1|7~84.25~300~1');

with t as (
    select string_to_array(x , '|') arr 
    from  tmp
)
select * , cardinality(arr) arr_len , split_part(arr[1],'~',2)
from t
  

пример вывода:

 "{1~41.5~50~1,2~43.72~1000~1,3~52.0~1~1,4~57.5~7500~1,5~68.0~8~1,6~80.95~6~1,7~84.25~300~1}";7;"41.5"
  

Я заинтересован в извлечении цены, которая представлена как второй элемент каждой записи массива (если она разделена символом ~), так что результат будет:

 41.5,43.72,52.0,...
  

при использовании split_part , которые возвращают только один результат определенного индекса массива,
и я не хочу жестко кодировать все индексы, так как они различаются.

предложения приветствуются.

Ответ №1:

Вот один из подходов:

 select t.*, w.prices
from tmp t
cross join lateral (
    select array_agg(split_part(v.z, '~', 2)) prices
    from regexp_split_to_table(t.x, '|') as v(z)
) w
  

В рамках подзапроса мы разделяем строку на строки, используя разделитель | ; затем мы агрегируем второй элемент каждой строки обратно в массив.

Вы можете явно указать, что хотите сохранить порядок элементов с помощью with ordinality :

 select t.*, w.prices
from tmp t
cross join lateral (
    select array_agg(split_part(v.z, '~', 2) order by v.n) prices
    from regexp_split_to_table(t.x, '|') with ordinality as v(z, n)
) w
  

Комментарии:

1. удивительно, на самом деле мне только что удалось получить что-то, используя: split_part(unnest(arr),’~’,2) price, за которым следует string_agg . Гарантирует ли это, что элементы будут возвращаться в том же порядке, что и исходная последовательность массива?

2. @Y.S: смотрите мое обновление о том, как гарантировать порядок элементов в результатах…