2011-12-16 24 views
5

Tôi có mối quan hệ nhiều-nhiều trong MySQL liên quan đến ba bảng: tickets, ticket_solutionssolutions. (. Một vé có thể có nhiều giải pháp, và các giải pháp áp dụng cho nhiều vé)Sử dụng phép nối bên ngoài bên trái cho mối quan hệ nhiều-nhiều, trong đó null được cho phép

Dưới đây là các cấu trúc bảng, đơn giản hóa:

tickets ticket_solutions solutions 
-----  -----    ----- 
id   ticket_id   id 
      solution_id   solution 

(Trong ví dụ này, tất cả các trường là INT trừ solutions.solution đó là VARCHAR.) Vì một số vé không được hoàn thành nên có thể không có giải pháp nào.

Tôi đã viết các truy vấn sau đây:

SELECT t.id, GROUP_CONCAT(DISTINCT sol.solution SEPARATOR ', ') solutions 
FROM tickets t 
LEFT JOIN ticket_solutions tsol ON (tsol.ticket_id = t.id) 
LEFT JOIN solutions sol ON (tsol.solution_id = sol.id) 
GROUP BY t.id DESC; 

Câu hỏi của tôi nằm với thứ hai LEFT JOIN. Trong bất kỳ trường hợp nào có mục nhập trong bảng liên kết (ticket_solutions) cho một vé nhất định, sẽ có luôn là là bản ghi để khớp trong solutions. Tuy nhiên, nếu tôi cố gắng sử dụng INNER JOIN thay vào đó, tôi không còn nhận được vé thiếu giải pháp.

Để suy nghĩ của tôi, thời gian duy nhất NULL giá trị sẽ xảy ra là trong mối quan hệ giữa tickets và bảng liên kết. (Vé chưa có giải pháp nào.)

Tôi có phải sử dụng LEFT JOIN giữa bảng liên kết và solutions mặc dù không có giá trị NULL trong mối quan hệ cụ thể đó?

Nếu không, cấu trúc truy vấn được đề xuất là gì?

Trả lời

7

Hãy thử nó theo cách này:

SELECT t.id, GROUP_CONCAT(DISTINCT sol.solution SEPARATOR ', ') solutions 
    FROM tickets t 
     LEFT JOIN ticket_solutions tsol 
      INNER JOIN solutions sol 
       ON (tsol.solution_id = sol.id) 
      ON (tsol.ticket_id = t.id) 
    GROUP BY t.id DESC; 
+0

Đây chính là điều tôi đang tìm kiếm. Cảm ơn bạn. – JYelton

1

Trong SQL gốc của bạn, bạn trái-join vé ticket_solutions, sau đó nội tham gia xem kết quả các giải pháp, trong đó sẽ đàn áp hàng mà không có một giải pháp tương ứng.

Trong câu trả lời Joe Stefanelli, mà cũng có thể được viết như

SELECT t.id, GROUP_CONCAT(DISTINCT sol.solution SEPARATOR ', ') 
FROM tickets t 
LEFT JOIN 
    (SELECT ticket_solutions.ticket_id AS id, solutions.solution AS solution 
    FROM ticket_solutions tsol 
    INNER JOIN solutions ON ticket_solutions.solution_id=solutions.id 
    ) AS sol ON t.id=sol.id 

lần đầu tiên bạn tham gia nội ticket_solutions với các giải pháp, sau đó trái tham gia quan điểm dẫn đến vé, do đó KHÔNG supressing vé trống.

0

Câu trả lời của Joe Stefanelli hoàn toàn đúng. Chỉ muốn thêm rằng bạn có thể sử dụng

IFNULL(GROUP_CONCAT(DISTINCT sol.solution SEPARATOR ', '), '') 

để có một chuỗi trống thay vì null.

Tuy nhiên, vì một số cuộc thảo luận khác về cùng một vấn đề đang gây nhầm lẫn, chỉ muốn liên kết fiddle này cũng như: http://www.sqlfiddle.com/#!2/54c6f/3/0

Các vấn đề liên quan