sql - 如何加入来自 jsonb 列的嵌套值?
问题描述
我有一个包含这些表的 PostgreSQL 11 数据库:
CREATE TABLE stats (
id integer NOT NULL,
uid integer NOT NULL,
date date NOT NULL,
data jsonb DEFAULT '[]'::json NOT NULL
);
INSERT INTO stats(id, uid, date, data) VALUES
(1, 1, '2020-10-01', '{"somerandomhash":{"source":"thesource"}}');
CREATE TABLE links(
id integer NOT NULL,
uuid uuid NOT NULL,
path text NOT NULL
);
INSERT INTO links(id, uuid, path) VALUES
(1, 'acbd18db-4cc2-f85c-edef-654fccc4a4d8', 'thesource');
我的目标是从表中创建一个新表reports
,但使用表中的新键。它看起来像这样:data
stats
links
CREATE TABLE reports(
id integer NOT NULL,
uid integer NOT NULL,
date date NOT NULL,
data jsonb DEFAULT '[]'::json NOT NULL
);
INSERT INTO reports(id, uid, date, data) VALUES
(1, 1, 2020-10-01, {"uuid":{"source":"thesource"});
为此,我尝试左连接表links
以检索uuid
列值 - 没有运气:
SELECT s.uid, s.date, s.data->jsonb_object_keys(data)->>'source' as path, s.data->jsonb_object_keys(data) as data, l.uuid
FROM stats s LEFT JOIN links l ON s.data->jsonb_object_keys(data)->>'source' = l.path
我尝试在左连接中使用 s.data->jsonb_object_keys(data)->>'source' 的结果,但出现错误:
ERROR: set-returning functions are not allowed in JOIN conditions
我尝试使用LATERAL
但仍然无效。
如何使这项工作?
解决方案
jsonb_object_keys()
是一个 set-returning 函数,不能按照您的方式使用 - 正如错误消息告诉您的那样。更重要的是,json_object_keys()
返回顶级key(s),但您似乎只对value感兴趣。请尝试jsonb_each()
:
SELECT s.id
, s.uid
, s.date
, jsonb_build_object(l.uuid::text, o.value) AS new_data
FROM stats s
CROSS JOIN LATERAL jsonb_each(s.data) o -- defaults to column names (key, value)
LEFT JOIN links l ON l.path = o.value->>'source';
db<>在这里摆弄
jsonb_each()
返回顶级键和值。仅使用value继续。
嵌套的 JSON 对象似乎具有常量键名'source'。所以加入条件是l.path = o.value->>'source'
。
最后,用 构建新jsonb
值jsonb_build_object()
。
虽然这如所展示的那样有效,但仍有几个问题:
以上假设在
stats.data
. 如果没有,你必须定义要做什么......以上假设 table 中总是有一个匹配项
links
。如果没有,你必须定义要做什么......最重要的是: 如果
data
您认为它是常规的,请考虑使用普通的“uuid”列(或将其删除,因为值在表中links
)和普通的列“源”来替换该jsonb
列。更简单,更高效。
推荐阅读
- python - 如何删除 PixelArray 的元素
- django - 在 django 中使用“ImageKit”对已关闭文件进行 I/O 操作
- arrays - 在 Shell 脚本中将 SED Commnd 的字符串输出存储在数组中
- python - 无法通过 loaddata 将 JSON Postgresql 数据库备份上传到新的 Django Heroku 应用程序
- c# - 有人可以解释为什么会发生此错误
- .net - ML.NET:使用 GUID 作为 ID 的推荐
- kubernetes - 如何识别谁在 Kubernetes 中编辑了 yaml 或属性文件?
- apache-kafka - Spring cloud stream kafka binder 连接到 docker-compose kafka
- .net-core - 使用 Apple 登录 - 未完成注册。点网核心
- c# - 无需请求即可将 ef.core db 实体映射到其他对象