MySQL-从查询中的一个表中获取值的关联列表,并从另一表中获取GROUP BY

时间:2020-05-25 16:09:14

标签: mysql sql

我有一个带有用户的表,一个带有分配的表以及一个带有各自与分配和用户相关联的任务的表。我想获取在给定作业中有任务的学生名单。 (针对我的问题,我尝试尽可能简化此数据库示例。)

这是一个SQL提琴: http://sqlfiddle.com/#!9/625a13/1

作为参考,数据库结构如下:

CREATE TABLE users (
  id SERIAL,
  name VARCHAR(32),
  PRIMARY KEY (id)
);

CREATE TABLE assignments (
  id SERIAL,
  title VARCHAR(45),
  assigned_by_user_id INT,
  PRIMARY KEY (id)
);

CREATE TABLE tasks (
  id SERIAL,
  user_id INT,
  assignment_id INT,
  complete INT,
  PRIMARY KEY (id)
);

INSERT INTO users VALUES (1, 'Student Joe'), (2, 'Student Fred'), (3, 'Teacher Bob');
INSERT INTO assignments VALUES (1, 'Math Homework', 3), (2, 'History Homework', 3), (3, 'Science Homework', 3);
INSERT INTO tasks VALUES (1,1,1,1), (2,1,2,1), (3,1,3,0), (4,2,1,1), (5,2,2,0), (6,2,3,0);

这是从该数据查询的示例:

SELECT a.id, a.title, u.name AS teacher_name, '' AS students_included,
(COUNT(CASE WHEN t.complete = 1 THEN t.id ELSE NULL END)/COUNT(t.id)*100) AS percent_complete
FROM assignments AS a
JOIN users AS u ON a.assigned_by_user_id = u.id 
LEFT JOIN tasks AS t ON a.id = t.assignment_id 
GROUP BY a.id 

以下是我所拥有的屏幕截图: DB sample

这是我的目标结果: DB sample - target

如何让查询返回与这些作业相关的学生姓名?在某些情况下,可能没有任何任务(没有学生),在某些情况下是一个学生,在某些情况下是多个学生。我想以某种方式在关联的列中获取学生姓名的数组/ CSV列表。

((我知道我可以对每一行进行单独的查询-例如在PHP中遍历结果时-并获得此结果,但这会很慢,麻烦且需要大量资源-我想尽可能用一个MySQL查询来获取学生姓名值-我只是想不起来怎么做。)

3 个答案:

答案 0 :(得分:1)

您可以使用GROUP_CONCAT(类似于Oracle中的LISTAGG),并且需要与USERS表再连接一次才能拉出学生的姓名

SELECT a.id, a.title, u.name AS teacher_name, GROUP_CONCAT(stu.name) AS students_included,
(COUNT(CASE WHEN t.complete = 1 THEN t.id ELSE NULL END)/COUNT(t.id)*100) AS percent_complete
FROM assignments AS a
JOIN users AS u ON a.assigned_by_user_id = u.id 
LEFT JOIN tasks AS t ON a.id = t.assignment_id
LEFT JOIN users AS stu ON stu.id = t.user_id 
GROUP BY a.id, a.title, u.name 

不要忘记将列添加到GROUP BY子句。

答案 1 :(得分:1)

您需要使用GROUP_CONCAT并加入另一个用户表

SELECT a.id, a.title, u.name AS teacher_name, GROUP_CONCAT(us.name)  AS students_included,
(COUNT(CASE WHEN t.complete = 1 THEN t.id ELSE NULL END)/COUNT(t.id)*100) AS percent_complete
FROM assignments AS a
JOIN users AS u ON a.assigned_by_user_id = u.id
LEFT JOIN tasks AS t ON a.id = t.assignment_id 
JOIN users AS us ON t.user_id = us.id 
GROUP BY a.id 

答案 2 :(得分:0)

我想我可能已经知道了...

SELECT a.id, a.title, u.name AS teacher_name, GROUP_CONCAT(u_s.name SEPARATOR ', ') AS students_included,
(COUNT(CASE WHEN t.complete = 1 THEN t.id ELSE NULL END)/COUNT(t.id)*100) AS percent_complete
FROM assignments AS a
LEFT JOIN tasks AS t ON a.id = t.assignment_id 
JOIN users AS u ON a.assigned_by_user_id = u.id 
LEFT JOIN users AS u_s ON t.user_id = u_s.id 
GROUP BY a.id 

仍然玩它...但是有人可能有更好的主意...