2011-12-16 4 views
5

Ho una relazione tabella molti-a-molti in MySQL che coinvolge tre tabelle: tickets, ticket_solutions e solutions. (. Il biglietto può avere più soluzioni, e le soluzioni applicabili a più biglietti)Uso del join esterno sinistro per la relazione molti-a-molti dove è consentito il valore zero

Ecco le strutture delle tabelle, semplificate:

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

(In questo esempio, tutti i campi sono INT tranne solutions.solution che è VARCHAR.) Poiché alcuni biglietti non sono completati, potrebbero non avere soluzioni.

ho scritto la seguente query:

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; 

La mia domanda è con la seconda LEFT JOIN. In qualsiasi situazione in cui esiste una voce nella tabella del linker (ticket_solutions) per un determinato ticket, ci sarà sempre un record corrispondente a solutions. Tuttavia, se provo a utilizzare uno INNER JOIN, non ottengo più ticket privi di soluzioni.

A mio avviso, l'unica volta che i valori NULL si verificheranno è nella relazione tra tickets e la tabella del linker. (Biglietto senza soluzioni ancora.)

Devo utilizzare un LEFT JOIN tra la tabella del linker e solutions anche se non ci saranno valori NULL in quella particolare relazione?

In caso contrario, qual è la struttura di query consigliata?

risposta

7

Prova in questo modo:

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

Questo è esattamente quello che stavo cercando. Grazie. – JYelton

1

In SQL originale che si uniscono a sinistra biglietti per ticket_solutions, poi interno-join la vista risultante a soluzioni, che sopprimere le righe senza un corrispondente soluzione.

In risposta di Joe Stefanelli, che potrebbe anche essere scritto come

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 

per la prima volta interna-join ticket_solutions alle soluzioni, poi a sinistra-join la vista risultante per i biglietti, quindi non sopprimendo i biglietti vuoti.

0

La risposta di Joe Stefanelli è assolutamente giusta. Volevo solo aggiungere che è possibile utilizzare

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

di avere una stringa vuota invece di null.

Tuttavia, dal momento che alcune altre discussioni circa lo stesso problema sono confuse, volevo solo collegare questo violino così: http://www.sqlfiddle.com/#!2/54c6f/3/0

Problemi correlati