Как создать пустой объект JSON в postgresql?
Datamodel
человек представлен в базе данных как строка мета-таблицы с именем и несколькими атрибутами, которые хранятся в таблице данных как пара ключ-значение (ключ и значение находятся в отдельных столбцах). упрощенная модель данных
сейчас есть запрос для получения всех пользователей (имя) со всеми их атрибутами (сведения). Атрибуты возвращаются как объект JSON в отдельный столбец. Вот пример:
name data
Florian { "age":25 }
Markus { "age":25, "color":"blue" }
Thomas {}
команда SQL выглядит следующим образом:
SELECT
name,
json_object_agg(d.key, d.value) AS data,
FROM meta AS m
JOIN (
JOIN d.fk_id, d.key, d.value AS value FROM data AS d
) AS d
ON d.fk_id = m.id
GROUP BY m.name;
теперь проблема, с которой я сталкиваюсь, заключается в том, что пользователям нравится Томас, которые не имеют никаких атрибутов, хранящихся в таблица, не отображаются с моей функцией выбора. Это потому, что он делает только JOIN
и LEFT OUTER JOIN
.
если бы я использовал LEFT OUTER JOIN
тогда я сталкиваюсь с проблемой, что json_object_agg
попробовать агрегировать NULL
ценности и умирает с ошибкой.
подходы
1. Возвращает пустой список ключей и значений
поэтому я попытался проверить, если пользователя NULL
и верните пустой массив so json_object_agg
просто создаст пустой JSON.
но на самом деле нет функции для создания пустого массива в SQL. Ближе всего я нашел следующее:--27-->
select '{}'::text[];
In комбинация с COALESCE
запрос выглядит так:
json_object_agg(COALESCE(d.key, '{}'::text[]), COALESCE(d.value, '{}'::text[])) AS data
но если я пытаюсь использовать это я получаю следующую ошибку:
ERROR: COALESCE types text and text[] cannot be matched
LINE 10: json_object_agg(COALESCE(d.key, '{}'::text[]), COALES...
^
Query failed
PostgreSQL said: COALESCE types text and text[] cannot be matched
так это выглядит во время выполнения d.key
- это одно значение, а не массив.
2. Разделите создание JSON и верните пустой список
поэтому я попытался взять json_object_agg
и заменить json_object
не совокупность ключи для меня:
json_object(COALESCE(array_agg(d.key), '{}'::text[]), COALESCE(array_agg(d.value), '{}'::text[])) AS data
но там я получаю ошибку это null value not allowed for object key
. Так что COALESCE
не проверяет, что массив пуст.
Qustion
Итак, есть ли функция, чтобы проверить, является ли объединенный столбец пустым, и если да, верните просто простой объект JSON?
или есть ли другое решение, которое решило бы мою проблему?
1 ответов
использовать left join
С coalesce()
. По умолчанию используется значение '{}'::json
.
select name, coalesce(d.data, '{}'::json) as data
from meta m
left join (
select fk_id, json_object_agg(d.key, d.value) as data
from data d
group by 1
) d
on m.id = d.fk_id;
name | data
---------+------------------------------------
Florian | { "age" : "25" }
Marcus | { "age" : "25", "color" : "blue" }
Thomas | {}
(3 rows)