我有一个 SQLite 表,其中一列包含一个包含 0 个或多个值的 JSON 数组。像这样的东西:
id|values
0 |[1,2,3]
1 |[]
2 |[2,3,4]
3 |[2]
我想要做的是将其“展开”到该列的数组中包含的所有不同值的列表中。
首先,我使用 JSON1 扩展的 json_each 函数从一行中提取值表:
SELECT
value
FROM
json_each(
(
SELECT
values
FROM
my_table
WHERE
id == 2
)
)
我可以改变 id(上面的 2)来选择表中的任何行。
现在,我尝试将其包装在递归 CTE 中,以便我可以将其应用于整个表中的每一行并将结果合并。作为第一步,我(大致)复制了上面的结果,如下所示:
WITH RECURSIVE result AS (
SELECT null
UNION ALL
SELECT
value
FROM
json_each(
(
SELECT
values
FROM
my_table
WHERE
id == 2
)
)
)
SELECT * FROM result;
作为下一步,我最初计划将 id 设置为变量并递增它(与文档中的第一个示例类似,但未能使其发挥作用。
我已经浏览了文档中的其他示例,但它们有点复杂,我无法将它们提炼出来以了解它们如何应用于此问题。
有人可以提供一个简单的例子来说明如何使用递归 CTE 解决这个问题(或类似的问题)吗?
当然,我的目标是在有或没有CTE的情况下解决问题,所以我也很高兴听到是否有更好的方法......
您不需要为此使用递归 CTE。
要为多个源行调用
json_each
,请使用联接:
SELECT t1.id, t2.value
FROM my_table AS t1
JOIN json_each((SELECT "values" FROM my_table WHERE id = t1.id)) AS t2;
我也有类似的问题。 在我的例子中,输入是 json 格式的 pmd 报告(使用格式
-f json
),像这样嵌套多次
{
"formatVersion": 0, "pmdVersion": "7.0.0-rc3", "timestamp": "2023-08-19T01:11:39.497+02:00",
"files": [
{ "filename": "D:\\A.cls", "violations": [ { ... }, { ... }, { ... }]}
,{ "filename": "D:\\B.cls", "violations": [ { ... }, { ... }, { ... }
],
"suppressedViolations": [],
"processingErrors": [],
"configurationErrors": []
}
数组中的每个文件
files: []
都可以有n个违规[v1, v2, v3]
我用来提取 json 对象和一些属性的 SQL 看起来像这样
SELECT ruleset, rule, priority, Count(Distinct filename) as files_affected FROM
(
SELECT
T1.id,
substr(json_extract(T1.Files, '$.filename'), 28) as filename,
json_extract(T2.value, '$.ruleset') as ruleset,
json_extract(T2.value, '$.rule') as rule,
json_extract(T2.value, '$.priority') as priority,
json_extract(T2.value, '$.description') as description
FROM (
SELECT PMD_Reports.id, jsonEachFiles.Value as Files
FROM PMD_Reports
,json_each(PMD_Reports.format_json, '$.files') AS jsonEachFiles
) AS T1, json_each(T1.Files, '$.violations') as T2
) as T3
GROUP BY T3.ruleset, T3.rule, T3.priority
崩溃了
json_each(PMD_Reports.format_json, '$.files')
打开 files-array
并导致每个文件一行。json_each(T1.Files, '$.violations')
解开每个文件的每个违规行为json_extract(T2.value, '$.priority') as priority,
读取违规的属性 priority
(T2.value
包含违规对象)