MySql查询两个表,并将第二个作为属性添加到第一个表的行中

问题描述

我正在建立一个教师界面,我有四个表格,分别是“教授”,“学生”,“所有作业”和“学生作业”(所有作业均针对单个学生)

我想向教授发送所有学生及其所有作业,但有些作业有多个作业,而有些作业则没有。我从第一个表中查询所有学生信息,现在我希望每一行(学生)都具有一个属性分配,该属性分配是第二个表中所有分配的数组。

学生

Name Class Grade
s1   1     A
s2   2     B

任务

Name Student Status 
a1   s1      done
a2   s1      done

我想得到:

[
{Name:s1,Class: 1,Grade: A,Assignments:[{Name:a1,Status: done},{Name:a2,Status: done}]},{Name:s2,Class: 2,Grade: B,Assignments:[]}
] 

我正在使用nodejs(MysqL模块)查询数据库


更新(来自评论

版本10.4.11-MariaDB – pro_programmer

解决方法

您可以使用JSON聚合:

select s.*,(
        select json_arrayagg(json_object('Name',a.name,'Status',a.status)) 
        from assignments a 
        where a.student = s.name
    ) assignments
from students s

如果无法使用json_arrayagg()(但json_object()的MariaDB 10.4),则一种解决方法将使用group_concat()

select s.*,(
        select concat('[',group_concat(json_object('Name',a.status),']') 
        from assignments a 
        where a.student = s.name
    ) assignments
from students s
,
-- MySQL 8+ needed
WITH cte AS ( SELECT Student Name,JSON_ARRAYAGG(JSON_OBJECT('Name',Name,Status)) Assignments
              FROM Assignments
              GROUP BY Student )
SELECT JSON_OBJECT( 'Name',Students.Name,'Class',Students.Class,'Grade',Students.Grade,'Assignments',COALESCE(cte.Assignments,JSON_ARRAY()) ) full_data
FROM Students
LEFT JOIN cte USING (Name);

-- MySQL 5.7.22 needed
SELECT JSON_OBJECT( 'Name',JSON_ARRAY()) ) full_data
FROM Students
LEFT JOIN ( SELECT Student Name,Status)) Assignments
            FROM Assignments
            GROUP BY Student ) cte USING (Name);

fiddle