[英]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.