2011-05-24 23 views
6

Actualmente tengo dos tablas similares a users y programs que están vinculados a través de una relación de muchos a muchos a través de una tabla link.Muchos a muchos tabla unirse a Pivote

mysql> select * from users; 
+----+----------+ 
| id | name  | 
+----+----------+ 
| 1 | Jonathan | 
| 2 | Little | 
| 3 | Annie | 
| 4 | Bob  | 
+----+----------+ 
4 rows in set (0.00 sec) 

mysql> select * from programs; 
+----+----------------------+ 
| id | name     | 
+----+----------------------+ 
| 1 | Microsoft Word  | 
| 2 | Microsoft Excel  | 
| 3 | Microsoft PowerPoint | 
+----+----------------------+ 
3 rows in set (0.00 sec) 

mysql> select * from link; 
+---------+------------+ 
| user_id | program_id | 
+---------+------------+ 
|  1 |   1 | 
|  1 |   2 | 
|  1 |   3 | 
|  2 |   2 | 
|  3 |   1 | 
|  3 |   4 | 
+---------+------------+ 
6 rows in set (0.00 sec) 

entiendo cómo unirse a las tablas y devuelve un resultado de este tipo:

mysql> select users.name, programs.name from linker 
    -> join users on users.id = linker.user_id 
    -> join programs on programs.id = linker.program_id; 
+----------+----------------------+ 
| name  | name     | 
+----------+----------------------+ 
| Jonathan | Microsoft Word  | 
| Jonathan | Microsoft Excel  | 
| Jonathan | Microsoft PowerPoint | 
| Little | Microsoft Excel  | 
| Annie | Microsoft Word  | 
+----------+----------------------+ 

Pero lo que realmente estoy buscando es un poco más complicado:

+----------+-----------------------------------------------------+ 
| name  | name            | 
+----------+-----------------------------------------------------+ 
| Jonathan | Microsoft Word,Microsoft Excel,Microsoft PowerPoint | 
| Little | Microsoft Excel          | 
| Annie | Microsoft Word          | 
+----------+-----------------------------------------------------+ 

I Supongo que hay un GROUP_CONCAT() arrojado al comando en alguna parte, pero parece que no puedo evitar que los resultados se vean así:

mysql> select users.name, group_concat(programs.name) from linker 
    -> join users on users.id = linker.user_id 
    -> join programs on programs.id = linker.program_id; 
+----------+------------------------------------------------------------------------------------+ 
| name  | group_concat(programs.name)              | 
+----------+------------------------------------------------------------------------------------+ 
| Jonathan | Microsoft Word,Microsoft Excel,Microsoft PowerPoint,Microsoft Excel,Microsoft Word | 
+----------+------------------------------------------------------------------------------------+ 

¿Alguien puede señalarme en la dirección correcta?

Respuesta

8

es necesario especificar un DISTINCT, es decir

select users.name, group_concat(DISTINCT programs.name) 

Consulte la documentación de MySQL here.

trate de cambiar su consulta a:

SELECT users.name, group_concat(programs.name) 
from users 
LEFT JOIN linker on linker.user_id = users.id 
LEFT JOIN programs on linker.program_id = programs.id 
GROUP BY users.id 

Esto le dará una null para cualquier usuario sin programas asociados con ellos. Para filtrarlos, simplemente agregue un WHERE programs.id IS NOT NULL.

+0

Esto elimina los valores duplicados, pero también limita los resultados a la primera fila. –

+0

no estoy seguro ... intente sacar primero a los usuarios. – Ryan

+0

Actualizó la respuesta - pruebe la consulta anterior. – Ryan

0
SELECT users.name, group_concat(programs.name) from linker 
INNER JOIN users on linker.user_id = users.id 
INNER JOIN programs on linker.program_id = programs.id 
GROUP BY users.id; 
+0

Esto solo devuelve la primera fila, incluidos los nombres de programas extra (duplicados). Creo que la prueba de igualdad se evalúa de la misma manera independientemente del orden. –

+0

@kpsfire ahhh! sí, tienes razón, error mío, el orden es importante cuando utilizas la combinación izquierda o derecha. – PachinSV

Cuestiones relacionadas