Выполните проверку после отмены вложения массива на основе значений столбца разделителя и суффикса

Ниже моя таблица:

ордрнбр название автомобиля описание идентификатор общая цена ind_price 132 Тесла 123@21000@bsd@23000@wer@41000 1 саР 84000 135 Тойота abc@21000@bsd@2300 2aqE 23300 138 Хонда абв@2100 3xДИ 2100 141 Киа текст 6iPQ 10000 145 Мазда нулевой 90ЭР 9000 147 BMW нулевой 69ТИ 90000

Здесь, в столбце описания, оно представлено как ключ@значение (при наличии разделителя «@»), т. е. k1@v1@k2@v2@k3@v3.

Мне нужно разделить столбец описания на основе разделителя @, получить значения и определить, равно ли каждое значение >= 10000. Если значение >= 10000, то мне нужно продублировать эту строку и суффикс ordrnbr на -1, -2 и -3 соответственно в зависимости от количества txn, которое превышает 10000 для этого ordrnbr, и столбец ind_price должен иметь это значение. захвачено, т. е.

ордрнбр название автомобиля описание идентификатор общая цена ind_price 132-1 Тесла 123@21000@bsd@23000@wer@41000 1 саР 84000 21000 132-2 Тесла 123@21000@bsd@23000@wer@41000 1 саР 84000 23000 132-3 Тесла 123@21000@bsd@23000@wer@41000 1 саР 84000 41000 135-1 Тойота abc@21000@bsd@2300 2aqE 23300 21000 141-1 Киа текст 6iPQ 10000 10000 147-1 BMW нулевой 69ТИ 90000 90000

Если @value меньше 10000, его необходимо отфильтровать.

Кроме того, если столбец описания не содержит разделителя, следует учитывать соответствующий столбец totprice, а если он меньше 10000, то его необходимо отфильтровать, в противном случае перед ordrnbr должен быть префикс -1, -2, -3 соответственно. .

Я попробовал использовать STRING_TO_ARRAY для разделения столбца описания на основе разделителя @ и использовать unnest для дублирования записей.

ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
0
72
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В вашем случае интересно, что вам нужно из строки получить двумерный массив.
Поэтому мы используем значение 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)

выход

ордрнбр название автомобиля описание идентификатор общая цена ind_price 132-1 Тесла 123@21000@bsd@23000@wer@41000 1 саР 84000 21000 132-2 Тесла 123@21000@bsd@23000@wer@41000 1 саР 84000 23000 132-3 Тесла 123@21000@bsd@23000@wer@41000 1 саР 84000 41000 135-1 Тойота abc@21000@bsd@2300 2aqE 23300 21000 141-1 Киа текст 6iPQ 10000 10000 147-1 BMW нулевой 69ТИ 90000 90000

Демо с подробностями

Есть пары ключ-значение из строки, не фильтруемые

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 ;
ордрнбр н номер 1 номер 2 Нкей Нвал описание 132 0 1 2 123 21000 123@21000@bsd@23000@wer@41000 132 1 3 4 БСД 23000 123@21000@bsd@23000@wer@41000 132 2 5 6 мы 41000 123@21000@bsd@23000@wer@41000 135 0 1 2 абв 21000 abc@21000@bsd@2300 135 1 3 4 БСД 2300 abc@21000@bsd@2300 138 0 1 2 абв 2100 абв@2100 141 0 1 1 текст нулевой текст

это блестящее решение. Дело в том, что если поле описания не содержит разделителя @, то эту запись следует отфильтровать, если общая цена <10000. Как нам этого добиться? Внесли поправки в свой вопрос.

Balaji Venkatachalam 15.06.2024 07:43

Попробуйте where s.Nval>=10000 or (s.Nval is null and totPrice>=10000)

ValNik 15.06.2024 07:45

Отлично – это прекрасно работает!

Balaji Venkatachalam 15.06.2024 07:52

Есть ли способ реализовать это решение без OF ORDINALITY в качестве API, который я использую, т. е. реализация DuckDB для postgres не поддерживает это? Можете ли вы мне помочь в этом?

Balaji Venkatachalam 18.06.2024 07:46

См. пример (dbfiddle.uk/7_nfgVZo).

ValNik 18.06.2024 08:12

Другие вопросы по теме