GROUP_CONCAT y LEFT_JOIN tema - No todas las filas devueltas
-
11-09-2019 - |
Pregunta
Digamos que mi esquema de base de datos es el siguiente:
T_PRODUCT
id_product (int, primary)
two entries: (id_product =1) , (id_product =2)
T_USER
id_user (int, primary)
id_product (int, foreign key)
name_user (varchar)
two entries: (id_product=1,name_user='John') , (id_product=1,name_user='Mike')
Si me quedo una primera consulta para obtener todos los productos con sus usuarios (si las hay), me sale esto:
SELECT T_PRODUCT.id_product, T_USER.name_user
FROM T_PRODUCT
LEFT JOIN T_USER on T_USER.id_product = T_PRODUCT.id_product;
>>
id_product name_user
1 John
1 Mike
2 NULL
Se ve bien para mí. Ahora bien, si yo quiero lo mismo, excepto que me gustaría tener productos por línea, con los nombres de usuario concatenados (si hay alguna otra manera, los usuarios NULL):
SELECT T_PRODUCT.id_product, GROUP_CONCAT(T_USER.name_user)
FROM T_PRODUCT
LEFT JOIN T_USER on T_USER.id_product = T_PRODUCT.id_product;
>>
id_product name_user
1 John,Mike
**expected output**:
id_product name_user
1 John,Mike
2 NULL
Si no hay usuarios de un producto, el GROUP_CONCAT impide MySQL desde la producción de una línea de este producto, a pesar de que hay un LEFT JOIN .
- ¿Es este un comportamiento esperado de MySQL?
- ¿Hay alguna manera de que pudiera obtener el resultado esperado usando GROUP_CONCAT u otra función?
Solución
Ah, encontrado mi respuesta:
Nunca se debe olvidar el GROUP BY cuando se trabaja con la cláusula GROUP_CONCAT .
Me estaba perdiendo GROUP BY T_PRODUCT.id_product
en mi segunda consulta.
Voy a dejar la pregunta en caso de que alguien es tan despistado como yo.
Editar
esta respuesta , pensé que también puede activar el modo SQL ONLY_FULL_GROUP_BY
para forzar a MySQL para lanzar un error en caso de que el GROUP BY o que sea incorrecto.
Otros consejos
Como alternativa, se puede utilizar una subconsulta, simplemente prueba de rendimiento
SELECT
T_PRODUCT.id_product,
(SELECT GROUP_CONCAT(T_USER.name_user)
FROM T_USER
WHERE T_USER.id_product = T_PRODUCT.id_product
)
FROM T_PRODUCT