我有类似于以下内容的 JSON:
{
"ANNOTATIONS": [
{
"Label": "CommingledProduct",
"Text": "NBP"
},
{
"Label": "CommingledVenue",
"Text": "OTC"
}
]
}
我需要将其解压缩到一个平面表格中,其中的列与注释标签相匹配。所以基于上述json的列变成:
- 混合产品
- comingled_venue
JSON 来自源表中的 json 字段并被解压到另一个表中。
我知道我可以编写如下代码:
INSERT INTO my_target_table (comingled_product, comingled_venue)
SELECT
payload->'ANNOTATIONS'->0->>'Text',
payload->'ANNOTATIONS'->1->>'Text'
FROM my_source_table;
但是,我宁愿不使用注释的序数。我更愿意使用一些语法来模仿下面的伪代码:
INSERT INTO my_target_table (comingled_product, comingled_venue)
SELECT
payload->'ANNOTATIONS'->'label="ComingledProduct"'->>'Text',
payload->'ANNOTATIONS'->'label="ComingledVenueID"'->>'Text'
FROM my_source_table;
谁能告诉我我正在努力实现的目标是否可行以及如何实现?我在示例中包含的注释不止两个,因此任何涉及多个连接的内容都可能是不行的。
使用 PostGres 10.7
最佳答案
WITH cte AS (
SELECT
elems.value
FROM
my_source_table,
json_array_elements(payload -> 'ANNOTATIONS') elems
)
SELECT
(SELECT value ->> 'Text' FROM cte WHERE value ->> 'Label' = 'CommingledProduct'),
(SELECT value ->> 'Text' FROM cte WHERE value ->> 'Label' = 'CommingledVenue')
- 将数组扩展为每个数组元素一行,并将此结果存储到 CTE 中以供进一步使用
- 此结果可用于查询期望值(无需进行两次扩展)
可以快一点:
SELECT
payload,
MIN(the_text) FILTER (WHERE label = 'CommingledProduct'),
MIN(the_text) FILTER (WHERE label = 'CommingledVenue')
FROM (
SELECT
payload::text AS payload,
elems ->> 'Label' AS label,
elems ->> 'Text' AS the_text
FROM
my_source_table,
json_array_elements(payload -> 'ANNOTATIONS') elems
) s
GROUP BY payload
关于json - 将 JSON 解包为平面格式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57496497/