繁体   English   中英

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

[英]MySQL - getting an associated list of values from one table in a query with a GROUP BY from another table

我有一个包含用户的表,一个包含分配的表,以及一个包含任务的表,每个任务都与分配和用户相关联。 我想获取在给定作业上有任务的学生列表。 (对于我的问题,我已尝试尽可能简化此数据库示例。)

这是一个 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 

这是我所拥有的屏幕截图: 数据库样本

这是我的目标结果: 数据库样本 - 目标

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

(我知道我可以对每一行进行单独的查询 - 例如在 PHP 中,当我遍历结果时 - 并得到这个结果,但这会很慢,很麻烦,而且资源密集 - 我想获得学生姓名值如果可能的话,使用单个 MySQL 查询 - 我只是想不出该怎么做。)

您可以使用 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 子句。

您需要使用 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 

我想我可能已经想通了……

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 

还在玩它......但有人可能有更好的主意......

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM