PostgreSQL JSONB - How to match the empty string keys

Схема таблицы:

create table test_table
(
    id serial not null,
    data jsonb
);

Пример данных:

INSERT INTO public.test_table (id, data) VALUES (1, '[{"": "VALUE1", "KEY2": "VALUE2"}, {"KEY1": "VALUE3", "KEY3": "VALUE4"}]');
INSERT INTO public.test_table (id, data) VALUES (2, '[{"''KEY1 ''": "VALUE1", "KEY2": "VALUE2"}, {"KEY3": "VALUE3", "KEY4": "VALUE4"}]');

SQL-запрос:

SELECT id, arr_elem
    FROM test_table AS tt, jsonb_array_elements(
        (
          SELECT data
          FROM test_table
          WHERE id = tt.id
        )
    ) AS arr_elem
    WHERE arr_elem#>'{KEY1}' IS NOT NULL

Я хотел бы настроить запрос выше, чтобы соответствовать следующим сценариям:

  1. Найти ключи с пустыми строками: Пример: "": "VALUE1"
  2. Найдите ключи только в одинарных кавычках: Пример: "''": "VALUE1"
  3. Найдите ключи с завершающими пробелами, заключенными в одинарные кавычки: Пример: "'KEY1 '": "VALUE1"

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

ОБНОВЛЕНИЕ 1:

Решение для 1: http://sqlfiddle.com/

SELECT id, arr_elem
    FROM test_table AS tt, jsonb_array_elements(
        (
          SELECT data
          FROM test_table
          WHERE id = tt.id
        )
    ) AS arr_elem
    WHERE arr_elem->'' IS NOT NULL

2 ответа

 select * from test_table
 where data->'' is not null /*gets rows with blank key names;


 select * from test_table
 where data->'''''' is not null; /*gets rows with '' as a key name;

Последнее немного сложнее...

 select * from test_table
 where exists 
 (select * from json_each(data) where key != rtrim(key))

Этот последний получает строку, где любой ключ!= Rtrim(ключ), так что должны получить элементы с конечными пробелами в именах ключей.

Другой ответ, который больше подходит для "массива объектов" json:

 select * from test_table
  where exists 
  (select * from jsonb_array_elements(data)
    where exists 
      (select * from 
        (select  jsonb_object_keys as k from 
          jsonb_object_keys(jsonb_array_elements)
        ) x 
        where x.k ='' or x.k ='''''' or x.k like '% '''
      )
  );

Примечание: внутреннее большинство (выберите json_object_keys в качестве k...) на самом деле не должно быть необходимо синтаксически, но я никогда не мог заставить его работать как меньший "один вкладыш".

Кроме того, этот запрос выбирает все 3 условия одновременно. Вы можете легко настроить его, чтобы отсеять эти сценарии или выполнить их по одному, изменив раздел 3 "или" в предложении where...

Объяснение: вам нужно сначала развернуть столбец данных до массива объектов, используя jsonb_array_elements, чтобы получить каждый объект, а затем повернуть, каждый из этих объектов должен быть расширен до массива ключей, который затем можно искать как обычный текст.

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