2011-12-16 7 views
5

Tengo una relación de tabla de muchos a muchos en MySQL que involucra tres tablas: tickets, ticket_solutions y solutions. (. Un billete puede tener múltiples soluciones, y las soluciones se aplican a múltiples entradas)Usando la combinación externa izquierda para la relación de muchos a muchos donde se permite nulo

Aquí están las estructuras de la tabla, simplificadas:

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

(En este ejemplo, todos los campos son INT excepto solutions.solution que es VARCHAR.) Como algunos tickets no están completos, es posible que no tengan ninguna solución.

He escrito la siguiente consulta:

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; 

Mi pregunta se encuentra con el segundo LEFT JOIN. En cualquier situación donde exista una entrada en la tabla de vinculador (ticket_solutions) para un ticket dado, habrá siempre sea un registro para que coincida con solutions. Sin embargo, si trato de usar un INNER JOIN, ya no recibo tickets que no tienen solución.

En mi opinión, la única vez que se producirán NULL valores será en la relación entre tickets y la tabla del enlazador. (Boleto sin soluciones todavía.)

¿Debo usar un LEFT JOIN entre la tabla de vinculador y solutions aunque no haya valores de NULL en esa relación en particular?

En caso negativo, ¿cuál es la estructura de consulta recomendada?

Respuesta

7

Trate de esta manera:

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

Esto es exactamente lo que estaba buscando. Gracias. – JYelton

1

En su SQL original que une a izquierda-entradas para ticket_solutions, a continuación interno a unirse a la vista resultante de soluciones, que serán suprimir filas sin una solución correspondiente.

En la respuesta de Joe Stefanelli, que también podría ser escrito como

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 

primero Unión interna ticket_solutions a las soluciones, luego a la izquierda a unirse a la vista resultante de boletos, por tanto, no suprimiendo las entradas vacías.

0

La respuesta de Joe Stefanelli es absolutamente correcta. sólo quería añadir que se puede utilizar

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

tener una cadena vacía en lugar de valores nulos.

Sin embargo, dado que algunas otras discusiones sobre el mismo problema son confusas, sólo quería vincular esta violín, así: http://www.sqlfiddle.com/#!2/54c6f/3/0

Cuestiones relacionadas