MYSQL json_object 有 1 个子项,子项与 2 个表组合在一起

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

我正在寻找如何合并/联合/等的答案。 JSON_Object 中的同一个子项内有 2 个表。

我有3张桌子。

  • 模块
  • data_fields(modu_id 模块的子级)
  • 报告(modu_id 的子模块)
CREATE TABLE modules (
  modu_id INT,
  appli_id INT,
  modu_title VARCHAR(50),
  t_modu_links INT
  
);
INSERT INTO modules VALUES (1,1,"Module 1",5);
INSERT INTO modules VALUES (2,1,"Module 2",6);

CREATE TABLE applications (
  appli_id INT,
  appli_title VARCHAR(50)
  
);
INSERT INTO applications VALUES (1,"application 1");
INSERT INTO applications VALUES (2,"application 2");

CREATE table data_fields (
  data_id INT,
  modu_id INT,
  data_title VARCHAR(50),
  t_data_links INT
  );
  
INSERT INTO data_fields VALUES(1,1,"Data field 1",1);
INSERT INTO data_fields VALUES(2,2,"Data field 2",2);
INSERT INTO data_fields VALUES(3,2,"Data field 3",1);

CREATE table reports (
  repo_id INT,
  modu_id INT,
  repo_title VARCHAR(50),
  t_repo_links INT
  );
  
INSERT INTO reports VALUES(1,1,"report 1",1);
INSERT INTO reports VALUES(2,2,"report 2",2);
INSERT INTO reports VALUES(3,2,"report 3",1);

SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));



我希望得到以下答复。

{
    "modu_id": 1,
    "modu_title": "Module 1",
    "data": [
            {
                "id": 1,
                "title": "data field 1",
                "t_links": 1,
                "datatype": "datafield"
            },
            {
                "id": 1,
                "title": "report 1"
                "t_links": 1,
                "datatype": "report"
            }
            ]
},
{
    "modu_id": 2,
    "modu_title": "Module 2",
    "data": [
            {
                "id": 2,
                "title": "data field 2",
                "t_links": 2,
                "datatype": "datafield"
            },
            {
                "id": 3,
                "title": "data field 3",
                "t_links": 1,
                "datatype": "datafield"
            }
            {
                "id": 2,
                "title": "report 2"
                "t_links": 1,
                "datatype": "report"
            },
            {
                "id": 3,
                "title": "report 3"
                "t_links": 1,
                "datatype": "report"
            }
            ]
}

我知道我必须创建 2 个子查询才能获取结果,但我很难将 2 个表放入 1 个 json_object。

我尝试过以下代码:

SELECT
    m.appli_id,
    a.appli_title,
    JSON_ARRAYAGG(
    JSON_OBJECT(
        "modu_id", m.modu_id,
        "modu_title", m.modu_title,
        "data", datafields)) as datafields,
    JSON_ARRAYAGG(
    JSON_OBJECT(
        "modu_id", m.modu_id,
        "modu_title", m.modu_title,
        "data", reports)) as reports,
    JSON_ARRAY_APPEND(JSON_ARRAYAGG(
    JSON_OBJECT(
        "modu_id", m.modu_id,
        "modu_title", m.modu_title,
        "data", datafields)),
        '$.data', 
    JSON_ARRAYAGG(
    JSON_OBJECT(
        "modu_id", m.modu_id,
        "modu_title", m.modu_title,
        "data", reports)))
FROM
(SELECT
    m.appli_id,
    m.modu_id,
    JSON_ARRAYAGG(
    JSON_OBJECT(
        "id", d.data_id,
        "title", d.data_title,
        "t_links", d.t_data_links,
        "Fieldtype", "datafield"
        )) as datafields
FROM modules as m
LEFT JOIN data_fields as d ON m.modu_id = d.modu_id
WHERE m.appli_id = 1
GROUP BY m.appli_id, m.modu_id
) as datafields

,
(SELECT
    m.appli_id,
    m.modu_id,
    JSON_ARRAYAGG(
    JSON_OBJECT(
        "id", r.repo_id,
        "title", r.repo_title,
        "t_links", r.t_repo_links,
        "Fieldtype", "report"
        )) as reports
FROM modules as m
LEFT JOIN reports as r ON m.modu_id = r.modu_id
WHERE m.appli_id = 1
GROUP BY m.appli_id, m.modu_id
) as reports
JOIN modules m USING(modu_id)
JOIN applications a ON a.appli_id = m.appli_id

GROUP BY m.appli_id

我知道这个代码不正确,因为它给了我双倍的记录。

希望大家能帮助我。

mysql json tree
1个回答
0
投票

您遇到的基本问题是两个子选择交叉连接,

架构(MySQL v8.0)

CREATE TABLE modules (
  modu_id INT,
  appli_id INT,
  modu_title VARCHAR(50),
  t_modu_links INT
  
);
INSERT INTO modules VALUES (1,1,"Module 1",5);
INSERT INTO modules VALUES (2,1,"Module 2",6);

CREATE TABLE applications (
  appli_id INT,
  appli_title VARCHAR(50)
  
);
INSERT INTO applications VALUES (1,"application 1");
INSERT INTO applications VALUES (2,"application 2");

CREATE table data_fields (
  data_id INT,
  modu_id INT,
  data_title VARCHAR(50),
  t_data_links INT
  );
  
INSERT INTO data_fields VALUES(1,1,"Data field 1",1);
INSERT INTO data_fields VALUES(2,2,"Data field 2",2);
INSERT INTO data_fields VALUES(3,2,"Data field 3",1);

CREATE table reports (
  repo_id INT,
  modu_id INT,
  repo_title VARCHAR(50),
  t_repo_links INT
  );
  
INSERT INTO reports VALUES(1,1,"report 1",1);
INSERT INTO reports VALUES(2,2,"report 2",2);
INSERT INTO reports VALUES(3,2,"report 3",1);

查询#1

SELECT 
    m.appli_id,
    a.appli_title,
    JSON_ARRAYAGG(JSON_OBJECT('modu_id',
                    m.modu_id,
                    'modu_title',
                    m.modu_title,
                    'data',
                    datafields)) AS datafields,
    JSON_ARRAYAGG(JSON_OBJECT('modu_id',
                    m.modu_id,
                    'modu_title',
                    m.modu_title,
                    'data',
                    reports)) AS reports,
    JSON_ARRAY_APPEND(JSON_ARRAYAGG(JSON_OBJECT('modu_id',
                            m.modu_id,
                            'modu_title',
                            m.modu_title,
                            'data',
                            datafields)),
            '$.data',
            JSON_ARRAYAGG(JSON_OBJECT('modu_id',
                            m.modu_id,
                            'modu_title',
                            m.modu_title,
                            'data',
                            reports)))
FROM
    (SELECT 
        m.appli_id,
            m.modu_id,
            JSON_ARRAYAGG(JSON_OBJECT('id', d.data_id, 'title', d.data_title, 't_links', d.t_data_links, 'Fieldtype', 'datafield')) AS datafields
    FROM
        modules AS m
    LEFT JOIN data_fields AS d ON m.modu_id = d.modu_id
    WHERE
        m.appli_id = 1
    GROUP BY m.appli_id , m.modu_id) AS datafields
    INNER JOIN 
    (SELECT 
        m.appli_id,
            m.modu_id,
            JSON_ARRAYAGG(JSON_OBJECT('id', r.repo_id, 'title', r.repo_title, 't_links', r.t_repo_links, 'Fieldtype', 'report')) AS reports
    FROM
        modules AS m
    LEFT JOIN reports AS r ON m.modu_id = r.modu_id
    WHERE
        m.appli_id = 1
    GROUP BY m.appli_id , m.modu_id) AS reports on datafields.appli_id = reports.appli_id 
    AND datafields.modu_id = reports.modu_id
        JOIN
    modules m ON m.modu_id = reports.modu_id
        JOIN
    applications a ON a.appli_id = m.appli_id
GROUP BY m.appli_id , a.appli_title;

在 DB Fiddle 上查看

© www.soinside.com 2019 - 2024. All rights reserved.