使用 JSON1 json_each 的递归 SQLite CTE

问题描述 投票:0回答:2

我有一个 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的情况下解决问题,所以我也很高兴听到是否有更好的方法......

sqlite recursion common-table-expression
2个回答
2
投票

您不需要为此使用递归 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;

0
投票

我也有类似的问题。 在我的例子中,输入是 json 格式的 报告(使用格式

-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
    包含违规对象)
© www.soinside.com 2019 - 2024. All rights reserved.