Ниже моя таблица:
Здесь, в столбце описания, оно представлено как ключ@значение (при наличии разделителя «@»), т. е. k1@v1@k2@v2@k3@v3.
Мне нужно разделить столбец описания на основе разделителя @, получить значения и определить, равно ли каждое значение >= 10000. Если значение >= 10000, то мне нужно продублировать эту строку и суффикс ordrnbr на -1, -2 и -3 соответственно в зависимости от количества txn, которое превышает 10000 для этого ordrnbr, и столбец ind_price должен иметь это значение. захвачено, т. е.
Если @value меньше 10000, его необходимо отфильтровать.
Кроме того, если столбец описания не содержит разделителя, следует учитывать соответствующий столбец totprice, а если он меньше 10000, то его необходимо отфильтровать, в противном случае перед ordrnbr должен быть префикс -1, -2, -3 соответственно. .
Я попробовал использовать STRING_TO_ARRAY для разделения столбца описания на основе разделителя @ и использовать unnest для дублирования записей.
В вашем случае интересно, что вам нужно из строки получить двумерный массив.
Поэтому мы используем значение ORDINALITY из UNNEST.
Поскольку нам нужна последовательность (ключ, значение), мы создадим пару через (n-1)/2.
Для n = {1,2, 3,4, 5,6} получите (n-1)/2 как {0,0, 1,1, 2,2}. Это значение для группы по.
См. пример
with suffixes as (
select ordrnbr,(nr-1)/2 N
,max(case when nr%2=1 then elem end) Nkey
,cast(max(case when nr%2=0 then elem end) as int) Nval
from test t
left join lateral unnest(string_to_array(t.description, '@'))
WITH ORDINALITY AS a(elem, nr) ON true
group by ordrnbr,(nr-1)/2
)
select concat(t.ordrnbr,'-',row_number()over(partition by t.ordrnbr order by s.N))ordrnbr
, vehiclename, description, id, totprice
,coalesce(s.Nval,totprice) ind_price
from test t
left join suffixes s on s.ordrnbr=t.ordrnbr
where s.Nval>=10000 or (s.Nval is null and totPrice>=10000)
выход
Демо с подробностями
Есть пары ключ-значение из строки, не фильтруемые
select ordrnbr,(nr-1)/2 N
,min(nr)nr1,max(nr) nr2
,max(case when nr%2=1 then elem end) Nkey
,max(case when nr%2=0 then elem end) Nval
,max(description) description
from test t
left join lateral unnest(string_to_array(t.description, '@'))
WITH ORDINALITY AS a(elem, nr) ON true
group by ordrnbr,(nr-1)/2
order by ordrnbr,(nr-1)/2 ;
Попробуйте where s.Nval>=10000 or (s.Nval is null and totPrice>=10000)
Отлично – это прекрасно работает!
Есть ли способ реализовать это решение без OF ORDINALITY в качестве API, который я использую, т. е. реализация DuckDB для postgres не поддерживает это? Можете ли вы мне помочь в этом?
См. пример (dbfiddle.uk/7_nfgVZo).
это блестящее решение. Дело в том, что если поле описания не содержит разделителя @, то эту запись следует отфильтровать, если общая цена <10000. Как нам этого добиться? Внесли поправки в свой вопрос.