2010-12-15 28 views
37

Tengo un problema con la función "GROUP_CONCAT" de MySQL. Voy a ilustrar mi problema utilizando una base de datos sencilla mesa de ayuda:MySQL: GROUP_CONCAT con 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.'); 

Tenga en cuenta que esta base de datos de help desk tiene dos entradas, cada una con dos entradas de solución. Mi objetivo es usar una declaración SELECT para crear una lista de todos los tickets en la base de datos con sus entradas de solución corrosponding. Esta es la instrucción SELECT que estoy usando:

SELECT Tickets.*, GROUP_CONCAT(Solutions.solution) AS CombinedSolutions 
FROM Tickets 
LEFT JOIN Solutions ON Tickets.id = Solutions.ticket_id 
ORDER BY Tickets.id; 

El problema con la instrucción SELECT anterior es que es regresando sólo una fila:

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. 

cuenta de que es devolver información sobre las entradas de 1 con tanto billete 1 de y entradas de la solución ticket 2.

¿Qué estoy haciendo mal? ¡Gracias!

Respuesta

71

Uso:

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 

alternativo:

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

Eso funciona! ¡Gracias! – Nick

+3

¿Pero por qué el método de Nick no funciona? Obviamente no, pero parece que debería. Me lo puedes explicar? – pbarney

+0

Hasta ahora entiendo que group_contact no se preocupa por las partes de la consulta, sino que agrupa todos los resultados intermedios. – jnovacho

1

creo que el comentario de @Dylan Valade es la respuesta más simple por lo que he publicado como otra respuesta: la simple adición de un GRUPO POR Tickets.id al SELECT del OP debería solucionar el problema. Solucionó mi propio problema.

Sin embargo, para las bases de datos que no son pequeñas, la respuesta aceptada, especialmente si hay algún predicado en Tickets.id, parece no implicar un escaneo total de la tabla y, mientras que el párrafo anterior arroja los resultados correctos, parece ser mucho menos eficiente en mi caso.