2010-12-15 3 views
37

У меня возникла проблема с функцией MySQL GROUP_CONCAT. Я проиллюстрирую мою проблему, используя простую базу данных справочной службы:MySQL: GROUP_CONCAT с LEFT JOIN

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 Tickets.*, GROUP_CONCAT(Solutions.solution) AS CombinedSolutions 
FROM Tickets 
LEFT JOIN Solutions ON Tickets.id = Solutions.ticket_id 
ORDER BY Tickets.id; 

Проблема с выше ЗЕЬЕСТ является, что возвращается только одна строка:

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.

Что я делаю неправильно? Благодаря!

ответ

71

Использование:

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 

Alternate:

SELECT t.*, 
      (SELECT GROUP_CONCAT(s.soution) 
      FROM SOLUTIONS s 
      WHERE s.ticket_id = t.ticket_id) AS combinedsolutions 
    FROM TICKETS t 
+1

Это работает! Спасибо! – Nick 2010-12-15 23:41:07

1

Я думаю, что комментарий @Dylan Valade является простым ответом, поэтому я отправляю это как еще один ответ: просто добавить GROUP BY Tickets.id к SELECT OP должен исправить проблему. Он исправил мою собственную проблему.

Однако для баз данных, которые не являются незначительными, принятый ответ, особенно если есть какие-либо предикаты на Tickets.id, похоже, не включает в себя общее сканирование таблицы, и поэтому, в то время как предыдущий абзац возвращает правильные результаты, это выглядит намного меньше эффективный в моем случае.