Манипуляция со строками Postgres

#postgresql

Вопрос:

У меня в таблице есть поле, содержащее строку, которая может следовать любому из 3 форматов:

  1. нулевой
  2. «[строка]»
  3. «Совпадают следующие поля: {строка=строка, строка=строка, строка=строка..}»

Для 1 мне нужен вывод : null Для 2 Мне нужен вывод : Для 3 мне нужно разделить каждую пару на каждую строку со столбцами [ключ] и [значение]

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

Был бы признателен, если бы кто-нибудь мог указать мне на лучшее решение ? Спасибо

 SELECT 
  h.nid, 
  trim(d.key) as "key", 
  trim(d.value) as "value"
FROM 
  (
          SELECT 
              r.*,
              cast(
                  replace(replace(replace(replace(
                        case 
                            when left(r.relation_details,25) = 'Following fields matched:' 
                            then right(r.relation_details, char_length(r.relation_details)-25)
                            when left(r.relation_details,1) = '[' 
                            then '{' || r.relation_details || '=' || r.relation_details || '}'
                            else null 
                        end 
                        ,'=' ,'":"'),',' ,'","'),'{' ,'{"'),'}' ,'"}')
              as json) as json
            FROM podium_core.pd_entity_relation r
  ) h
  JOIN 
  json_each_text(h.json) d ON true
 

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

1. Я предлагаю предварительно обработать ваши данные за пределами Postgres, используя что-то вроде Notepad , а затем импортировать их позже.

2. Спасибо, но данные взяты из стороннего приложения, основанного на postgres. Я не могу изменить исходные данные.

Ответ №1:

Ваш запрос не работает должным образом для меня (с примером данных » {a=b, c=d, e=f}» я получаю пустую строку).

Моя попытка, я не уверен, что результат моего запроса именно то, что вы хотите.

Я конвертирую все строки в формат массива, затем удаляю их (используя разделитель запятых). Я разделяю строки, содержащие знак равенства, на массив, а затем получаю результат в двух столбцах (ключ, значение).

Стол:

 CREATE TABLE pd_entity_relation (
    relation_details character varying(100)
);
 

Входные данные (примеры данных):

 INSERT INTO pd_entity_relation VALUES (null);
INSERT INTO pd_entity_relation VALUES ('[x]');
INSERT INTO pd_entity_relation VALUES ('{a=b, c=d, e=f}');
 

Запрос:

 SELECT 
    '[' || f[1] || ']' AS key,
    '[' || CASE WHEN cardinality(f) > 1 THEN f[2] ELSE f[1] END || ']' AS value
 
FROM (
    SELECT regexp_split_to_array(UNNEST(CASE WHEN relation_details IS NULL THEN ARRAY[NULL] ELSE replace(replace(relation_details, '[', '{'), ']', '}')::text[] END), '=') AS f
    FROM pd_entity_relation
) AS sq
 

Выход:

 |  key | value |
|:----:|:-----:|
| null | null  |
| [x]  | [x]   |
| [a]  | [b]   |
| [c]  | [d]   |
| [e]  | [f]   |
 

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

1. Это блестяще, спасибо 🙂 Третья вставка должна быть » Следующие поля совпадают:{a=b, c=d, e=f}», но теперь я это учел, и ваш код работает блестяще. В будущем я постараюсь предоставить более точные исходные данные 😉

2. Добро пожаловать @SimonB! Моя ошибка: я не внимательно прочитал ваш запрос. Проверьте мой запрос с большим количеством данных, чтобы убедиться, что он работает правильно.