#postgresql
Вопрос:
У меня в таблице есть поле, содержащее строку, которая может следовать любому из 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! Моя ошибка: я не внимательно прочитал ваш запрос. Проверьте мой запрос с большим количеством данных, чтобы убедиться, что он работает правильно.