MySQL: GROUP_CONCAT с LEFT JOIN
У меня возникла проблема с функцией MySQL GROUP_CONCAT. Я проиллюстрирую свою проблему, используя простую базу данных справки:
CREATE TABLE Tickets (
id INTEGER NOT NULL PRIMARY KEY,
requester_name VARCHAR(255) NOT NULL,
description TEXT NOT NULL);
CREATE TABLE Solutions (
id INTEGER NOT NULL PRIMARY KEY,
ticket_id INTEGER NOT NULL,
technician_name VARCHAR(255) NOT NULL,
solution TEXT NOT NULL,
FOREIGN KEY (ticket_id) REFERENCES Tickets.id);
INSERT INTO Tickets VALUES(1, 'John Doe', 'My computer is not booting.');
INSERT INTO Tickets VALUES(2, 'Jane Doe', 'My browser keeps crashing.');
INSERT INTO Solutions VALUES(1, 1, 'Technician A', 'I tried to solve this but was unable to. I will pass this on to Technician B since he is more experienced than I am.');
INSERT INTO Solutions VALUES(2, 1, 'Technician B', 'I reseated the RAM and that fixed the problem.');
INSERT INTO Solutions VALUES(3, 2, 'Technician A', 'I was unable to figure this out. I will again pass this on to Technician B.');
INSERT INTO Solutions VALUES(4, 2, 'Technician B', 'I re-installed the browser and that fixed the problem.');
Обратите внимание, что в этой базе данных службы поддержки есть два билета, каждый из которых имеет две записи решения. Моя цель состоит в том, чтобы использовать оператор SELECT для создания списка всех билетов в базе данных с их агрессивными ответами. Это оператор SELECT, который я использую:
SELECT Tickets.*, GROUP_CONCAT(Solutions.solution) AS CombinedSolutions
FROM Tickets
LEFT JOIN Solutions ON Tickets.id = Solutions.ticket_id
ORDER BY Tickets.id;
Проблема с приведенным выше оператором SELECT заключается в том, что он возвращает только одну строку:
id: 1
requester_name: John Doe
description: My computer is not booting.
CombinedSolutions: I tried to solve this but was unable to. I will pass this on to Technician B since he is more experienced than I am.,I reseated the RAM and that fixed the problem.,I was unable to figure this out. I will again pass this on to Technician B.,I re-installed the browser and that fixed the problem.
Обратите внимание, что он возвращает информацию о билете 1 как с билетами 1, так и с билетами 2.
Что я делаю неправильно? Спасибо!
Ответы
Ответ 1
Использование:
SELECT t.*,
x.combinedsolutions
FROM TICKETS t
LEFT JOIN (SELECT s.ticket_id,
GROUP_CONCAT(s.soution) AS combinedsolutions
FROM SOLUTIONS s
GROUP BY s.ticket_id) x ON x.ticket_id = t.ticket_id
Альтернативные
SELECT t.*,
(SELECT GROUP_CONCAT(s.soution)
FROM SOLUTIONS s
WHERE s.ticket_id = t.ticket_id) AS combinedsolutions
FROM TICKETS t
Ответ 2
Я думаю, что комментарий @Dylan Valade - это самый простой ответ, поэтому я отправляю его как еще один ответ: просто добавив GROUP BY Tickets.id в OP SELECT, вы должны исправить эту проблему. Он исправил мою собственную проблему.
Однако для нечетных баз данных принятый ответ, особенно если есть какие-либо предикаты на Tickets.id, похоже, не включает в себя общее сканирование таблицы, и поэтому, в то время как предыдущий абзац возвращает правильные результаты, он выглядит намного менее эффективным в моем случае.
Ответ 3
Вам просто нужно добавить GROUP_BY:
SELECT Tickets.*, GROUP_CONCAT(Solutions.solution) AS CombinedSolutions FROM Tickets
LEFT JOIN Solutions ON Tickets.id = Solutions.ticket_id
GROUP_BY Tickets.id
ORDER BY Tickets.id;