json - 为每条记录解析一个带有 FOR 循环的 JSON 列?
问题描述
作为 Postgres 和 SQL 的新手,我在 Postgres 9.6 中有以下场景:
table1
"Myjson" JSON
"DateOfAcquisition" DATE
"Id" INT
里面有一个列表,我用"Myjson"
循环遍历它FOR
。
我的目标是将每个 json 列表的元素table1
放在另一个表中:
table2
jsonelem1 INT
jsonelem2 INT
"DateOfAcquisition" DATE
"Id" INT
我已经编写了以下代码来解析 json 字段,但我不确定如何为for
第一个表的每条记录运行循环。
DO
$BODY$
DECLARE
omgjson json := myjsonfield; -- this should change for every row of the first table
i json;
myJsonelem1 INT;
myJsonelem2 INT;
begin
FOR i IN SELECT * FROM json_array_elements(omgjson)
loop
myJsonelem2 i->> 'jsonsubfield'::INT;
INSERT INTO destinationTable VALUES (myJsonelem2,DateOfAcquisition);
END LOOP;
END;
$BODY$ language plpgsql
解决方案
基于集合的方法通常比循环快得多(并且更短且不易出错)。
INSERT INTO table2(myfield, data) -- cleaner: explicit target columns
SELECT k."myField", j.i ->> 'data'
FROM table1 k, json_array_elements(k."ScrapedJson" -> 'calendar_days') j(i)
WHERE NOT k."HasBeenProcessed"
-- ORDER BY ??? -- you might want to order rows favorably?
隐式LATERAL
连接是这里的关键技术。
... FROM table1 k, json_array_elements(...) ...
简称:
... FROM table1 k
CROSS JOIN LATERAL json_array_elements(...) ...
显然,"ScrapedJson" -> 'calendar_days'
是 JSON 数组,而不是您在问题中写的“列表”。
有关的:
旁白
帮自己一个忙,避免在 Postgres 中使用双引号的 CaMeL 案例名称。您的问题和答案中引用和未引用标识符的狂野混合只会让人感到困惑。我在您的问题中引用了列名,以在某种程度上与您的答案相匹配。我的长期建议:只使用合法的、小写的、未引用的名称。
考虑数据类型jsonb
而不是json
大多数工作负载。
推荐阅读
- python - 如何解决我的点击并不总是准确的问题
- sql-server - 如何在 Azure Data Studio 中折叠所有区域
- mysql - 如果新值不为空,如何更新行字段
- shopify - Shopify - 将文件 CSV 订购到文本文件
- c++ - 解码霍夫曼树 C++
- netsuite - Suitelets 何时触发用户事件脚本?
- amazon-web-services - 将用户限制在一个区域 AWS
- python - 如何在过滤条件pyspark中使用函数
- ios - 使用 AVAudioRecorder 录制后,AVAudioPlayer 不通过扬声器播放
- python - 等待函数,直到它在 python 异步 IO 中收到回调