Получение имен ключей полей JSON в Postgres

У меня есть данные, которые используют JSON в качестве помеченных объединений, так что объект верхнего уровня содержит только один дочерний объект. Тип дочернего объекта зависит от его ключевого имени в родительском, а не от отдельного поля «тег», как это обычно бывает в структурах C.

e.g.

{"circle":{"radius":10}}
{"square":{"side":10}})
{"rectangle":{"width":10,"height":20}})

Это очень хорошо работает со схемами JSON и буферами протокола.

Я прочитал: https://www.postgresql.org/docs/9.6/static/functions-json.html.

Я борюсь с функциями Postgres JSON. Как мне сделать SQL-эквивалент следующего Javascript

Object.keys({"circle":{"radius":10}})[0]               (== `"circle")
Object.keys({"square":{"side":10}})[0]                 (== `"square")
Object.keys({"rectangle":{"width":10,"height":20}})[0] (== `"rectangle")

с полями JSONB?


person fadedbee    schedule 24.07.2017    source источник
comment
Это выглядит актуальным: stackoverflow.com/a/38347906/129805   -  person fadedbee    schedule 24.07.2017


Ответы (1)


Вы можете использовать jsonb_object_keys, который похож на его аналог Javascript. Например:

SELECT jsonb_object_keys(json_column)
FROM MyTable

Очевидно, это возвращает набор записей. Однако, если вы знаете, что в объекте JSON всегда будет только один ключ, просто используйте его как подзапрос, если это необходимо. Например:

SELECT *
FROM MyTable
WHERE 'cicle' = (
  SELECT jsonb_object_keys(json_column)
  FROM MyTable
)

ИЗМЕНИТЬ

Вы можете получить скалярное значение следующим образом:

SELECT json_build_array(jsonb_object_keys(json_column)) -> 0
FROM MyTable

Обратите внимание, что это json (т.е. "circle", а не circle). Если вам нужно текстовое значение, используйте оператор ->>.

person Martin Campbell    schedule 24.07.2017
comment
Есть ли способ получить первый ключ объекта, т.е. превратить набор записей в скаляр? - person fadedbee; 24.07.2017
comment
Я отредактировал ответ, чтобы показать пример получения скалярного значения. - person Martin Campbell; 24.07.2017