我具有类似于以下内容的JSON:
{
"ANNOTATIONS": [
{
"Label": "CommingledProduct",
"Text": "NBP"
},
{
"Label": "CommingledVenue",
"Text": "OTC"
}
]
}
我需要将其解压缩到带有与注释标签匹配的列的平面表中。因此,基于上述json的列将变为:
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
答案 0 :(得分:2)
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')
可能会快一点:
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
答案 1 :(得分:2)
@ S-Man的答案很好,您应该将其用于postgres 10.7。 json_path将添加到postgres 12中,这将使您可以做一些更接近伪代码的操作,但只能使用jsonb(而不是json):
INSERT INTO my_target_table (comingled_product, comingled_venue)
SELECT jsonb_path_query(payload,
'$.ANNOTATIONS[*] ? (@.Label == "CommingledProduct")')->>'Text',
jsonb_path_query(payload,
'$.ANNOTATIONS[*] ? (@.Label == "CommingledVenue")')->>'Text'
FROM my_source_table;
jsonb_path_query语法需要一点时间来弄清楚,但它基本上是返回ANNOTATIONS数组的元素,其Label等于CommingledProduct或CommingledVenue。 jsonb_path_query返回一个jsonb对象,因此我们可以使用->>运算符从该对象获取'Text'的值。