PostgreSQL с использованием COALESCE или других условных выражений в поле SET - PullRequest
2 голосов
/ 10 апреля 2020

У меня есть PostgreSQL v10 DB со следующими значениями:

CREATE TABLE test (
  id INT,
  custom_fields jsonb not null default '{}'::jsonb,
  guest_profile_id character varying(100)
 );
INSERT INTO test (id, custom_fields) VALUES (1, '[{"protelSurname": "Smith", "servicio_tags": ["protel-info"], "protelUniqueID": "[{\"ID\":\"Test1-ID\",\"Type\":\"21\",\"ID_Context\":\"GHA\"}{\"ID\":\"4842148\",\"Type\":\"1\",\"ID_Context\":\"protelIO\"}]",    "protelGivenName": "Seth"}, {"value": "Test", "display_name": "Traces", "servicio_tags": ["trace"]}, {...}]');
INSERT INTO test (id, custom_fields) VALUES (2, '[{"protelSurname": "Smith", "servicio_tags": ["protel-info"], "protelUniqueID": "[{\"ID\":\"Test2-ID\",\"Type\":\"21\",\"ID_Context\":\"GHA\"},{\"ID\":\"4842148\",\"Type\":\"1\",\"ID_Context\":\"protelIO\"}]", "protelGivenName": "Seth"}, {"value": "Test2", "display_name": "Traces", "servicio_tags": ["trace"]}, {...}]');
INSERT INTO test (id, custom_fields) VALUES (3, '[{"value": "Test3-ID", "display_name": "Test", "servicio_tags": ["profile-id"]}, {...}]');
INSERT INTO test (id, custom_fields) VALUES (4, '[{"value": "Test4-ID", "display_name": "Test", "servicio_tags": ["person-name"]}, {...}]');   

У меня есть запрос, который работает и сохраняет значения из строки custom_field в столбец guest_profile_id в той же строке:

UPDATE guest_group
SET guest_profile_id = (
SELECT x ->> 'ID'
FROM jsonb_array_elements(custom_fields) AS field,
     jsonb_array_elements((field ->> 'protelUniqueID') :: jsonb) AS dd(x)
WHERE value @> '{"servicio_tags": ["protel-info"]}'::jsonb
AND x->>'ID_Context' = 'protelIO' 
);

Но это работает только для первых двух строк. Поэтому я хочу использовать следующие фрагменты запроса, чтобы скопировать Test3-ID в строке 3 в столбец guest_profile_id и Test4-ID в строке 4 в столбец guest_profile_id.

1.

SELECT field ->>'value'
cross join lateral jsonb_array_elements(custom_fields) AS field
WHERE value @> '{"servicio_tags": ["profile-id"]}'::jsonb

2.

SELECT field ->>'value'
cross join lateral jsonb_array_elements(custom_fields) AS field
WHERE value @> '{"servicio_tags": ["person-name"]}'::jsonb

Моя проблема: я не знаю, как использовать COALESCE или другие условные выражения для объединения этих небольших запросов. Поскольку это должно быть возможно, если первый запрос использует NULL для установки поля, COALESCE должен помочь мне проигнорировать это значение и перейти к следующему фрагменту запроса.

Желает результата: я хочу, чтобы все значения TestX-ID из таблицы выше копируются в столбец guest_profile_id в той же строке.

Моя попытка:

 UPDATE test
 SET guest_profile_id = COALESCE((
     SELECT x ->> 'ID'
     FROM jsonb_array_elements(custom_fields) AS field,
          jsonb_array_elements((field ->> 'protelUniqueID') :: jsonb) AS dd(x)
     WHERE value @> '{"servicio_tags": ["protel-info"]}'::jsonb
     AND x->>'ID_Context' = 'protelIO'),(
     SELECT field ->>'value'
     cross join lateral jsonb_array_elements(custom_fields) AS field
     WHERE value @> '{"servicio_tags": ["profile-id"]}'::jsonb),(
     SELECT field ->>'value'
     cross join lateral jsonb_array_elements(custom_fields) AS field
     WHERE value @> '{"servicio_tags": ["person-name"]}'::jsonb));

Дает мне:

ОШИБКА: синтаксическая ошибка в или около "креста" LINE 9: поперечное соединение боковых jsonb_array_elements (custom_fields) ...

Большое спасибо за помощь!

1 Ответ

0 голосов
/ 11 апреля 2020

Еще несколько скобок справились с select_queries:

guest_profile_id = COALESCE((first_select_query),((second_select_query)), ((…)))

UPDATE test
SET guest_profile_id = COALESCE((
SELECT x ->> 'ID'
FROM jsonb_array_elements(custom_fields) AS field,
     jsonb_array_elements((field ->> 'protelUniqueID') :: jsonb) AS dd(x)
 WHERE value @> '{"servicio_tags": ["protel-info"]}'::jsonb
 AND x->>'ID_Context' = 'protelIO' LIMIT 1),((
 SELECT field ->>'value'
 FROM jsonb_array_elements(custom_fields) AS field
 WHERE value @> '{"servicio_tags": ["profile-id"]}'::jsonb LIMIT 1)), ((
 SELECT field ->>'value'
 FROM jsonb_array_elements(custom_fields) AS field
 WHERE value @> '{"servicio_tags": ["person-name"]}'::jsonb LIMIT 1
 )));

Здесь ссылка на скрипку: Запрос, который работает

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...