Извлечение значений из массива в Redshift SQL

У меня есть несколько массивов, хранящихся в "транзакциях" таблицы Redshift в следующем формате:

id, total, breakdown
1, 100, [50,50]
2, 200, [150,50]
3, 125, [15, 110]
...
n, 10000, [100,900]

Поскольку этот формат для меня бесполезен, мне нужно немного обработать его, чтобы получить значения. Я пытался использовать регулярное выражение для его извлечения.

SELECT regexp_substr(breakdown, '\[([0-9]+),([0-9]+)\]')
FROM transactions

но я получаю сообщение об ошибке, которое говорит

Unmatched ( or \(
Detail: 
-----------------------------------------------
error:  Unmatched ( or \(
code:      8002
context:   T_regexp_init
query:     8946413
location:  funcs_expr.cpp:130
process:   query3_40 [pid=17533]
--------------------------------------------

В идеале я хотел бы получить x и y как свои собственные столбцы, чтобы я мог выполнить соответствующую математику. Я знаю, что могу сделать это довольно легко на python, PHP или чем-то подобном, но меня интересует чистое решение SQL - отчасти потому, что я использую онлайн-редактор SQL (Mode Analytics), чтобы легко отображать его как панель инструментов.

Спасибо за вашу помощь!


person Ajax729    schedule 06.02.2016    source источник


Ответы (3)


Если breakdown действительно является массивом, вы можете сделать это:

select id, total, breakdown[1] as x, breakdown[2] as y
from transactions;

Если разбивка не массив, а, например, столбец varchar, вы можете преобразовать его в массив, если замените квадратные скобки фигурными скобками:

select id, total, 
       (translate(breakdown, '[]', '{}')::integer[])[1] as x,
       (translate(breakdown, '[]', '{}')::integer[])[2] as y
from transactions;
person a_horse_with_no_name    schedule 06.02.2016

Вы можете попробовать это:

SELECT REPLACE(SPLIT_PART(breakdown,',',1),'[','') as x,REPLACE(SPLIT_PART(breakdown,',',2),']','') as y FROM transactions;

Я пробовал это с redshift db, и это сработало для меня.

Подробное объяснение:

  • SPLIT_PART(breakdown,',',1) даст вам [50.
  • SPLIT_PART(breakdown,',',2) даст вам 50].
  • REPLACE(SPLIT_PART(breakdown,',',1),'[','') заменит [ и даст только 50.
  • REPLACE(SPLIT_PART(breakdown,',',2),']','') заменит ] и даст только 50.
person Isha Garg    schedule 24.05.2016

Знайте, что это старый пост. Но если кому-то нужен более простой способ

select json_extract_array_element_text('[100,101,102]', 2);

выход: 102

person theDbGuy    schedule 24.08.2018