Usando GROUP_CONCAT en la subconsulta en MySQL
group-concat mysql-error-1242 (5)
Sí, la solución de soulmerge está bien. Pero necesitaba una consulta donde tuve que recopilar datos de más tablas secundarias, por ejemplo:
- mesa principal: sesiones ( sesiones de presentación) (uid, nombre, ...)
- Primera tabla secundaria: eventos con la clave session_id (uid, session_uid, date, time_start, time_end)
- 2ª mesa secundaria: accesorios necesarios (ordenador portátil, proyector, micrófonos, etc.) con la clave session_id (uid, session_uid, accessory_name)
- 3rd child table: session_presenters (personas presentadoras) con key session_id (uid, session_uid, presenter_name, address ...)
Cada sesión tiene más filas en las tablas de tablas secundarias (más horarios, más accesorios)
Y necesitaba recopilar en una colección para cada sesión para mostrar en la fila de mineral (algunos de ellos):
session_id | session_name | date | time_start | time_end | accessories | presenters
Mi solución (después de muchas horas de experimentos):
SELECT sessions.uid, sessions.name,
,(SELECT GROUP_CONCAT( `events`.date SEPARATOR ''</li><li>'')
FROM `events`
WHERE `events`.session_id = sessions.uid ORDER BY `events`.date) AS date
,(SELECT GROUP_CONCAT( `events`.time_start SEPARATOR ''</li><li>'')
FROM `events`
WHERE `events`.session_id = sessions.uid ORDER BY `events`.date) AS time_start
,(SELECT GROUP_CONCAT( `events`.time_end SEPARATOR ''</li><li>'')
FROM `events`
WHERE `events`.session_id = sessions.uid ORDER BY `events`.date) AS time_end
,(SELECT GROUP_CONCAT( accessories.name SEPARATOR ''</li><li>'')
FROM accessories
WHERE accessories.session_id = sessions.uid ORDER BY accessories.name) AS accessories
,(SELECT GROUP_CONCAT( presenters.name SEPARATOR ''</li><li>'')
FROM presenters
WHERE presenters.session_id = sessions.uid ORDER BY presenters.name) AS presenters
FROM sessions
Entonces no es necesario UNIRSE o AGRUPAR POR. Otra cosa útil para mostrar datos amigables (cuando los "eco"):
- puede ajustar events.date, time_start, time_end, etc. en "<UL> <LI> ... </ LI> </ UL>", por lo que "<LI> </ LI>" se usa como separador en la consulta separará los resultados en elementos de la lista.
Espero que esto ayude a alguien. ¡Aclamaciones!
Tengo una consulta de MySQL en la que quiero incluir una lista de ID de otra tabla. En el sitio web, las personas pueden agregar ciertos elementos, y las personas pueden agregar esos artículos a sus favoritos. Básicamente quiero obtener la lista de identificación de las personas que han dado preferencia a ese artículo (esto es un poco simplificado, pero esto es a lo que se reduce).
Básicamente, hago algo como esto:
SELECT *,
GROUP_CONCAT((SELECT userid FROM favourites WHERE itemid = items.id) SEPARATOR '','') AS idlist
FROM items
WHERE id = $someid
De esta forma, podría mostrar quién favourited algún elemento, dividiendo la idlist más adelante en una matriz en PHP más adelante en mi código, sin embargo, estoy obteniendo el siguiente error de MySQL:
1242 - Subquery devuelve más de 1 fila
Pensé que ese era el punto de usar GROUP_CONCAT
lugar de, por ejemplo, CONCAT
? ¿Voy por esto de la manera incorrecta?
Ok, gracias por las respuestas hasta ahora, parece funcionar. Sin embargo, hay una trampa. Los artículos también se consideran favoritos si fueron agregados por ese usuario. Entonces necesitaría una verificación adicional para verificar si creator = userid. ¿Alguien puede ayudarme a idear una forma inteligente (y con suerte eficiente) de hacer esto?
¡Gracias!
Editar: Intenté hacer esto:
SELECT [...] LEFT JOIN favourites ON (userid = itemid OR creator = userid)
Y idlist está vacío. Tenga en cuenta que si uso INNER JOIN
lugar de LEFT JOIN
, obtengo un resultado vacío. Aunque estoy seguro de que hay filas que cumplen con el requisito de ON.
El propósito de GROUP_CONCAT es correcto, pero la subconsulta es innecesaria y causa el problema. Pruebe esto en su lugar:
SELECT ITEMS.id,GROUP_CONCAT(FAVOURITES.UserId)
FROM FAVOURITES INNER JOIN ITEMS ON ITEMS.Id = FAVOURITES.ItemId
WHERE ITEMS.Id = $someid
GROUP BY ITEMS.ID
Creo que es posible que el "ID de usuario = elemento" sea incorrecto, ¿no debería ser así?
SELECT ITEMS.id,GROUP_CONCAT(FAVOURITES.UserId) AS IdList
FROM FAVOURITES
INNER JOIN ITEMS ON (ITEMS.Id = FAVOURITES.ItemId OR FAVOURITES.UserId = ITEMS.Creator)
WHERE ITEMS.Id = $someid
GROUP BY ITEMS.ID
No puede acceder a las variables en el ámbito externo en tales consultas (no puede usar items.id
allí). Deberías intentar algo como
SELECT
items.name,
items.color,
CONCAT(favourites.userid) as idlist
FROM
items
INNER JOIN favourites ON items.id = favourites.itemid
WHERE
items.id = $someid
GROUP BY
items.name,
items.color;
Expanda la lista de campos según sea necesario (nombre, color ...).
OP casi lo hace bien. GROUP_CONCAT
debe estar envolviendo las columnas en la subconsulta y no la subconsulta completa (descarto el separador porque la coma es la predeterminada):
SELECT i.*,
(SELECT GROUP_CONCAT(userid) FROM favourites f WHERE f.itemid = i.id) AS idlist
FROM items i
WHERE i.id = $someid
Esto producirá el resultado deseado y también significa que la respuesta aceptada es parcialmente errónea, porque puede acceder a variables de ámbito externo en una subconsulta.