MySQL - получение связанного списка значений из одной таблицы в запросе с GROUP BY из другой таблицы - PullRequest
2 голосов
/ 25 мая 2020

У меня есть таблица с пользователями, таблица с назначениями и таблица с задачами, каждая из которых связана с назначением и пользователем. Я хочу получить список студентов, у которых есть задача по данному заданию. (Я попытался максимально упростить этот образец БД для своего вопроса.)

Вот SQL Fiddle: 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, поскольку я l oop через результаты - и получить этот результат, но это будет медленным, громоздким и ресурсоемким - я хотел бы получить значения имени ученика с помощью одного запроса MySQL, если это вообще возможно - я просто могу ' Не думаю, как это сделать.)

Ответы [ 3 ]

1 голос
/ 25 мая 2020

Вы можете использовать GROUP_CONCAT (аналогично LISTAGG в Oracle), и вам потребуется еще одно соединение с таблицей 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 голос
/ 25 мая 2020

Вам необходимо использовать 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 
0 голосов
/ 25 мая 2020

Думаю, я понял это ...

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 

Все еще играю с ним ... но у кого-то может быть идея получше ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...