如何在 postgresql 中创建一个空的 JSON 对象?
How to create an empty JSON object in postgresql?
数据模型
一个人在数据库中表示为元 table 行,具有名称和多个属性,这些属性存储在数据中 table 作为键值对(键和值在单独的列)。
简化数据模型
现在有一个查询来检索所有用户 (name) 及其所有属性 (data)。这些属性在单独的列中被 return 编辑为 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;
问题
现在我面临的问题是,像 Thomas 这样的用户没有任何属性存储在 key-value table,不显示在我的 select 函数中。这是因为它只执行 JOIN
而没有执行 LEFT OUTER JOIN
.
如果我要使用 LEFT OUTER JOIN
,那么我 运行 会遇到问题,json_object_agg
会尝试聚合 NULL
值并因错误而死。
方法
1。 Return 键和值的空列表
所以我尝试检查用户的 key-column 是否为 NULL
和 return 是否为空数组,因此 json_object_agg
会只需创建一个空的 JSON 对象。
但是SQL中并没有真正创建空数组的函数。我发现的最近的东西是:
select '{}'::text[];
结合 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 创建和 return 空列表
所以我尝试使用 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
不检查数组是否为空。
问题
那么,是否有检查连接列是否为空的函数,如果是,return 只是一个简单的 JSON 对象?
或者是否有任何其他解决方案可以解决我的问题?
将 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)
数据模型
一个人在数据库中表示为元 table 行,具有名称和多个属性,这些属性存储在数据中 table 作为键值对(键和值在单独的列)。
现在有一个查询来检索所有用户 (name) 及其所有属性 (data)。这些属性在单独的列中被 return 编辑为 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;
问题
现在我面临的问题是,像 Thomas 这样的用户没有任何属性存储在 key-value table,不显示在我的 select 函数中。这是因为它只执行 JOIN
而没有执行 LEFT OUTER JOIN
.
如果我要使用 LEFT OUTER JOIN
,那么我 运行 会遇到问题,json_object_agg
会尝试聚合 NULL
值并因错误而死。
方法
1。 Return 键和值的空列表
所以我尝试检查用户的 key-column 是否为 NULL
和 return 是否为空数组,因此 json_object_agg
会只需创建一个空的 JSON 对象。
但是SQL中并没有真正创建空数组的函数。我发现的最近的东西是:
select '{}'::text[];
结合 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 创建和 return 空列表
所以我尝试使用 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
不检查数组是否为空。
问题
那么,是否有检查连接列是否为空的函数,如果是,return 只是一个简单的 JSON 对象?
或者是否有任何其他解决方案可以解决我的问题?
将 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)