[英]How would I join two tables in MySQL (many to one) and get a specific JSON output (as shown below)
我將如何加入MySQL中的兩個表(多對一)並獲得特定的JSON output(如下圖)
注意:請不要將其標記為重復
之前發布的一個問題與此非常相似,但在幾點上並不相同。
這不是我要找的,這個問題與此不同: Mysql concat 和 group_concat
我在這篇文章的底部放了一個更長的描述和更多的細節,為什么不應該將其標記為重復,以及它有何不同。
要求:
output JSON 將是一個數組(teams),數組(struct)的每個元素都將包含一個數組(persons)。
頂級數組屬於父表“teams”(JSON 數組的每個元素包含單行數據),嵌套數組屬於子表“persons”,它與父表具有多對一關系。
如果一個簡單的 select 僅從一張表完成: select * from <child_table>;
我得到了父表的 id(主鍵),但是在 JSON 結果中,除了父主鍵,我還想顯示父表的另一個字段(父表中的字段值,而不僅僅是行 id / 鍵,這對 JSON 輸出沒有幫助)。
此處提供: .sql 文件以創建數據庫、架構、插入數據(以測試解決方案)
create schema if not exists test;
use test;
create table if not exists team
(
id int unsigned auto_increment primary key,
team_name varchar(30) unique not null,
description text
);
use test;
create table if not exists person
(
id int unsigned auto_increment primary key,
id_team int unsigned not null,
person_name varchar(40) not null,
notes varchar(40) not null,
constraint team_person unique (id, id_team),
foreign key (id_team) references team (id)
);
-- insert teams (2)
use test;
insert into team(team_name)
values ('team1');
insert into team(team_name)
values ('team2');
insert into team(team_name)
values ('team3');
-- insert persons (x2 per team = 4)
use test;
insert into person(id_team, person_name)
values ((select id from team where team_name = 'team1'),
'john');
insert into person(id_team, person_name)
values ((select id from team where team_name = 'team1'),
'tom');
insert into person(id_team, person_name)
values ((select id from team where team_name = 'team1'),
'marie');
-- team 2
insert into person(id_team, person_name)
values ((select id from team where team_name = 'team2'),
'scott');
insert into person(id_team, person_name)
values ((select id from team where team_name = 'team2'),
'mark');
我需要 output JSON 看起來像這樣(完全展開 - 兩個 arrays 具有來自兩個表的值):
您在這里看到的是一組團隊,“團隊”表中每行一個 JSON 元素。
在每個元素中,一組人,每行一個 JSON 元素,來自“人”表,代表多對一關系。
{
"team_persons": [
{
"team": "team1",
"id_team": 1,
"persons": [
{
"id_person": 1,
"personaName": "john"
},
{
"id_person": 2,
"personaName": "allison"
}
]
},
{
"team": "team2",
"id_team": 2,
"persons": [
{
"id_person": 3,
"personaName": "katrina"
},
{
"id_person": 4,
"personaName": "scott"
}
]
}
]
}
output中可以看到,JSON output中的每條記錄中都顯示了父表字段: id_team & team_name 。
JSON中有兩個arrays:
我知道SELECT JSON_OBJECT / JSON_ARRAYAGG會涉及。 我不確定如何在兩個表的 SQL 連接中同時使用兩者,以實現所需的自定義 JSON output。
SQL 中的兩個表的連接如下所示:
select t.id id_team, p.id id_person, p.person_name, t.team_name
from team t,
person p
where t.id = p.id_team;
謝謝你!
請不要將其標記為重復,它不是:
我只處理兩個表,其中 JSON output 需要從一個非常頂級的數組開始(與其他帖子不同)。
{
"team_persons": [
引用的帖子和方法存在問題:
有一種更好、更現代的方法可以使用其他內置 MySQL 函數來執行此操作。
請不要關閉這個問題。 要求非常不同。
我需要一種使用的方法: JSON_OBJECT / JSON_ARRAYAGG and NOT CONCAT and NOT GROUP_CONCAT 。 並且也僅在兩個非常簡單的表上。
問問題時,如果試圖解決的最簡單(不准確)的事情能幫助其他人 map 他們的問題就成了問題。 在下面的問題中,我去除了所有復雜性以提供一個簡單示例。
我希望提供一個更容易理解的問題,其他人可能會從中受益(使用復制表結構的代碼),以及一個更精致的答案,因為我相信給出的答案對於更簡單的用例來說可以變得更簡單,並且更容易理解。
SELECT
JSON_PRETTY(
JSON_OBJECT(
'team_persons', JSON_ARRAYAGG(
JSON_OBJECT(
'team', team,
'id_team', id_team,
'persons', persons
)
)
)
) AS _result
FROM (
SELECT
t.id AS id_team,
t.team_name AS team,
JSON_ARRAYAGG(
JSON_OBJECT(
'id_person', p.id,
'personName', p.person_name
)
) AS persons
FROM team t JOIN person p ON t.id = p.id_team
GROUP BY id_team
) AS p;
在 MySQL 8.0.28 上測試過,但它也應該適用於 MySQL 5.7.22(或更高版本)。
包括空隊是棘手的。 一開始只能使用 LEFT OUTER JOIN,但隨后它會抱怨,除非我將 GROUP BY 更改為引用基列,而不是別名:
...
FROM team t LEFT OUTER JOIN person p ON t.id = p.id_team
GROUP BY t.id
但是,這可能不會產生您想要的結果,我假設它是一個空的 JSON 數組。 因為外部聯接的結果確實有一行,但是帶有 NULL,所以您會得到一個帶有 NULL 的假團隊成員:
{
"team": "team3",
"id_team": 3,
"persons": [
{
"id_person": null,
"personName": null
}
]
}
一種解決方法是將當前查詢與 JOIN 與另一個排除連接查詢聯合起來:
SELECT
JSON_PRETTY(
JSON_OBJECT(
'team_persons', JSON_ARRAYAGG(
JSON_OBJECT(
'team', team,
'id_team', id_team,
'persons', persons
)
)
)
) AS _result
FROM (
SELECT
t.id AS id_team,
t.team_name AS team,
JSON_ARRAYAGG(
JSON_OBJECT(
'id_person', p.id,
'personName', p.person_name
)
) AS persons
FROM team t JOIN person p ON t.id = p.id_team
GROUP BY t.id
UNION
SELECT
t.id,
t.team_name,
JSON_ARRAY()
FROM team t LEFT OUTER JOIN person p ON t.id = p.id_team
WHERE p.id_team IS NULL
) AS p;
UNION 的后半部分返回一個文字空數組,因為反正團隊中沒有人。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.