如何 SQL 查询特定 JSON 格式的父子节点?

Posted

技术标签:

【中文标题】如何 SQL 查询特定 JSON 格式的父子节点?【英文标题】:How to SQL query parent-child for specific JSON format? 【发布时间】:2019-08-08 06:16:36 【问题描述】:

我期待这个 JSON 用于我的 jQuery 代码:


  "projects": [
    
      "id": "1",
      "project_name": "Carmichael House",
      "parent_id": "0",
      "children": [
        
          "id": "2",
          "project_name": "Carmichael Kitchen",
          "parent_id": "1"
        ,
        
          "id": "3",
          "project_name": "Carmichael Bathroom",
          "parent_id": "1"
        
      ]
    ,
    
      "id": "2",
      "project_name": "Dowd Apartment",
      "parent_id": "0",
      "children": [
        
          "id": "4",
          "project_name": "Dowd Kitchen",
          "parent_id": "2"
        
      ]
    
  ]

这些数据将来自mysqltbl_projects

id
project_name
parent_id

SQL SELECT 查询应该是什么,以便它输出 1 个平面表,可以轻松转换为 JSON(在 phpjavascript/jQuery 中)?

我的方法是否正确?

【问题讨论】:

哪个版本的 MySQL?这很重要,因为只有更高版本支持递归公用表表达式。 MySql 5.7 版 【参考方案1】:

您可以直接从 MySQL 生成 JSON 内容。这是一个适用于 MySQL 5.7 或更高版本的解决方案。

首先,考虑function JSON_OBJECT(),它为表中的每条记录生成一个 JSON 对象:

SELECT 
    p.*, 
    JSON_OBJECT('id', id, 'project_name', project_name, 'parent_id', parent_id) js
FROM tbl_projects p;

根据您的示例数据,返回:

| id  | project_name        | parent_id | js                                                               |
| --- | ------------------- | --------- | ---------------------------------------------------------------- |
| 1   | Carmichael House    | 0         | "id": 1, "parent_id": 0, "project_name": "Carmichael House"    |
| 2   | Carmichael Kitchen  | 1         | "id": 2, "parent_id": 1, "project_name": "Carmichael Kitchen"  |
| 3   | Carmichael Bathroom | 1         | "id": 3, "parent_id": 1, "project_name": "Carmichael Bathroom" |
| 4   | Dowd Apartment      | 0         | "id": 4, "parent_id": 0, "project_name": "Dowd Apartment"      |
| 5   | Dowd Kitchen        | 4         | "id": 5, "parent_id": 4, "project_name": "Dowd Kitchen"        |

为了生成您预期的输出,我们将自 JOIN 表查找子记录,并使用 aggregate function JSON_ARRAYAGG() 生成内部 JSON 数组。一个额外的聚合级别将所有内容都放入一个对象中。如您的示例数据所示,我假设根项目有 parent_id = 0 并且只有一层层次结构:

SELECT JSON_OBJECT('projects', JSON_ARRAYAGG(js)) results
FROM (
    SELECT JSON_OBJECT(
        'id', p.id, 
        'project_name', p.project_name, 
        'parent_id', p.parent_id,
        'children', JSON_ARRAYAGG(
            JSON_OBJECT(
                'id', p1.id, 
                'project_name', p1.project_name, 
                'parent_id', p1.parent_id
            )
        )
    ) js
    FROM tbl_projects p
    LEFT JOIN tbl_projects p1 ON p.id = p1.parent_id
    WHERE p.parent_id = 0
    GROUP BY p.id, p.project_name, p.parent_id
) x

产量:

| results                                                                                                                                                                                                                                                                                                                                                              |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| "projects": ["id": 1, "children": ["id": 2, "parent_id": 1, "project_name": "Carmichael Kitchen", "id": 3, "parent_id": 1, "project_name": "Carmichael Bathroom"], "parent_id": 0, "project_name": "Carmichael House", "id": 4, "children": ["id": 5, "parent_id": 4, "project_name": "Dowd Kitchen"], "parent_id": 0, "project_name": "Dowd Apartment"] |

Demo on DB Fiddle

【讨论】:

哇。你和 JSON_OBJECT() 一样棒。 Welcome Rollor... 这样的反馈在我耳中听起来很棒!

以上是关于如何 SQL 查询特定 JSON 格式的父子节点?的主要内容,如果未能解决你的问题,请参考以下文章

用java代码将从数据库中取出的具有父子关系的数据转成json格式

如何在递归 SQL 查询中查找子树中的所有节点?

如何从我的特定 sql 查询中返回 json?

PySpark - 如何输出带有特定字段的 JSON?

SQL递归查询所有子节点

200分求助!SQL递归查询所有子节点