该表有一个id和step\u数据列。
id | step_data
--------------
a1 | {...}
a2 | {...}
a3 | {...}
其中step\u数据是嵌套结构,如下所示,其中元数据的实际键可以位于 events
物体。
{
"events": [
{
"timestamp": "2021-04-07T17:46:13.739Z",
"meta": [
{
"key": "length",
"value": "0.898"
},
{
"key": "height",
"value": "607023104"
},
{
"key": "weight",
"value": "33509376"
}
]
},
{
"timestamp": "2021-04-07T17:46:13.781Z",
"meta": [
{
"key": "color",
"value": "0.007"
},
{
"key": "count",
"value": "641511424"
},
{
"key": "age",
"value": "0"
}
]
}
]
}
我可以提取一个像 length
很容易。
select cast(metadata ->> 'value' as double precision) as length,
id
from (
select jsonb_array_elements(jsonb_array_elements(step_data #> '{events}') #> '{meta}') metadata,
id
from table
) as parsed_keys
where metadata @> '{
"key": "length"
}'::jsonb
怠速10.898a20.800
但是我真正需要的是从几个已知的键中提取元数据作为列,比如 length
以及 color
. 我不知道如何在拆分数组后高效地获取另一列 jsonb_array_elements()
.
有没有一种不用打电话就能做到这一点的有效方法 jsonb_array_elements()
再来一次,把每一个都连接起来?例如,结果集如下所示。
IDLENGTHCOLORWATA10.8980.00733509376a20.8001.00015812391
使用postgres 11.7。
3条答案
按热度按时间0pizxfdo1#
对于postgres 11,我只能考虑取消两个级别的测试,然后聚合回一个键/值对,从中可以提取所需的键:
有了postgres 12,你可以写得简单一点:
eqqqjvef2#
交叉表()
任何postgres版本。
你可以把结果输入
crosstab()
函数来透视结果。你需要额外的模块tablefunc
安装。如果您不熟悉,请先阅读以下基本说明:postgresql交叉表查询
db<>在这里摆弄(全部演示)
应该提供最佳性能,特别是对于许多列。
请注意,我们不需要显式强制转换
double precision
(float
).crosstab()
过程text
无论如何输入,结果将强制为列定义列表中给定的类型。如果其中一个键出现多次,则最后一行获胜(您可以向$1中的查询添加确定性排序顺序,以便最后对首选行进行排序。示例:要获取每个键的最低值:
带筛选子句的条件聚合
对于postgres 9.4或更新版本。
请参见:
使用附加(不同)筛选器聚合列
在12年级或更高的时候,我会把表现与
jsonb_path_query_first()
. 一匹马提供了一个解决方案。ljsrvy3e3#
此查询是一个选项: