2011-12-16 28 views
5

在MySQL中,我有一個多對多表關係,涉及三個表:tickets,ticket_solutionssolutions。 (一種票證可能有多種解決方案,和解決方案應用到多個門票)使用左外部聯接實現允許空值的多對多關係

下面是表結構,簡化了:

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

(在這個例子中,所有字段都除了solutions.solutionVARCHARINT。 )由於一些票未完成,他們可能沒有任何解決方案。

我已經寫了下面的查詢:

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; 

我的問題出在第二LEFT JOIN。在給定票證的鏈接器表(ticket_solutions)中存在條目的任何情況下,總會有成爲匹配solutions的記錄。但是,如果我嘗試使用INNER JOIN,我不再購買缺乏解決方案的門票。

以我的想法,NULL值將發生的唯一時間是在tickets和鏈接器表之間的關係。 (沒有任何解決方案的票證)

我必須在鏈接器表和solutions之間使用LEFT JOIN,即使在該特定關係中不會有NULL值?

如果不是,建議的查詢結構是什麼?

回答

7

試試這樣說:

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

這正是我一直在尋找。謝謝。 – JYelton 2011-12-16 19:41:29

1

在原來的SQL你離開聯接門票ticket_solutions,然後內合併產生的視圖解決方案,這將剿行沒有相應的解決方案。結果視圖

在喬·斯特凡內利的答案,這也可以寫成

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 

你先內加入ticket_solutions到解決方案,然後左鍵加入到票,因此不supressing空票。

0

Joe Stefanelli的回答絕對正確。 只是想補充一點,你可以使用

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

有一個空字符串,而不是空值。

然而,由於對同樣的問題其他一些討論是混亂的,只是想這個小提琴以及鏈接:http://www.sqlfiddle.com/#!2/54c6f/3/0

相關問題