2011-12-16 7 views
5

Mam relację wiele do wielu w MySQL z udziałem trzech tabel: tickets, ticket_solutions i solutions. (. Bilet może mieć różne rozwiązania i rozwiązania zastosować do wielu biletów)Używanie lewego sprzężenia zewnętrznego dla relacji wiele do wielu gdzie dozwolona jest wartość zerowa

Oto struktury tabeli, uproszczone:

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

(W tym przykładzie, wszystkie pola są INT wyjątkiem solutions.solution która VARCHAR. Ponieważ niektóre bilety nie są ukończone, mogą nie mieć żadnych rozwiązań.

Pisałem następujące zapytanie:

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; 

Moje pytanie leży po drugiej LEFT JOIN. W każdej sytuacji, w której istnieje wpis w tabeli linkerów (ticket_solutions) dla danego biletu, będzie zawsze rekordem do dopasowania w solutions. Jednak jeśli spróbuję użyć numeru INNER JOIN, nie otrzymam już biletów, w których brakuje rozwiązań.

Do mojego myślenia, jedynymi wartościami, które pojawią się NULL, jest stosunek między tickets a tabelą linkera. (Bilet bez żadnych rozwiązań.)

Czy muszę używać LEFT JOIN między tabelą linkera a solutions, mimo że w tej konkretnej relacji nie będzie wartości NULL?

Jeśli nie, jaka jest zalecana struktura zapytania?

Odpowiedz

7

Spróbuj to tak:

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

To jest dokładnie to, czego szukałem. Dziękuję Ci. – JYelton

1

W oryginalnym SQL Zostawiłeś dołącz bilety ticket_solutions, a następnie łączenie wewnętrzne wynikowy widok do rozwiązań, które będą wyciszyć wierszy bez odpowiedniego rozwiązania.

W odpowiedzi Joe Stefanelli, która może być również zapisane jako

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 

najpierw łączenie wewnętrzne ticket_solutions do rozwiązania, a następnie w lewo dołącz wynikowy widok na bilety, a więc nie tłumiąc pustych bilety.

0

Odpowiedź Joe Stefanelli ma absolutną rację. Chciałem tylko dodać, że można użyć

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

mieć pusty ciąg zamiast null.

Jednakże, ponieważ niektóre inne dyskusje o tym samym problemem są mylące, po prostu chciałem, aby połączyć te skrzypce, a także: http://www.sqlfiddle.com/#!2/54c6f/3/0

Powiązane problemy