web-dev-qa-db-ja.com

MySQL:LEFT JOINを使用したGROUP_CONCAT

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.');

このヘルプデスクデータベースには2つのチケットがあり、それぞれに2つのソリューションエントリがあることに注意してください。私の目標は、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ステートメントの問題は、1行しか返さないことです。

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とチケット2の両方のソリューションエントリでチケット1の情報を返していることに注意してください。

私は何を間違えていますか?ありがとう!

50
Nick

使用する:

   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
85
OMG Ponies

@Dylan Valadeのコメントは最も簡単な答えだと思うので、別の答えとして投稿しています:GROUP BY Tickets.idをOPのSELECTに追加するだけで問題が解決するはずです。それは私自身の問題を修正しました。

ただし、小さくないデータベースの場合、特にTickets.idに述語が存在する場合、テーブル全体のスキャンが含まれていないため、前の段落で正しい結果が返されますが、私の場合はあまり効率的ではないようです。

2
ghr

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;
1
Frederic WOEHL