En MySQL, puede devolver los resultados de su consulta como una lista separada por comas usando GROUP_CONCAT()
función.
El GROUP_CONCAT()
La función se creó específicamente con el propósito de concatenar el conjunto de resultados de una consulta en una lista separada por una coma o un delimitador de su elección.
Este artículo proporciona ejemplos de cómo funciona todo.
Los datos
Primero, usemos los siguientes datos en nuestros primeros ejemplos:
USE Solutions; SELECT TaskName FROM Tasks;
Resultado:
+-------------------+ | TaskName | +-------------------+ | Do garden | | Feed cats | | Paint roof | | Take dog for walk | | Relax | | Feed cats | +-------------------+
Ejemplo básico
Aquí hay un ejemplo básico para demostrar el GROUP_CONCAT()
función:
SELECT GROUP_CONCAT(TaskName) FROM Tasks;
Resultado:
+------------------------------------------------------------------+ | GROUP_CONCAT(TaskName) | +------------------------------------------------------------------+ | Do garden,Feed cats,Paint roof,Take dog for walk,Relax,Feed cats | +------------------------------------------------------------------+
Como puede ver, cada fila del conjunto de resultados se ha concatenado en una sola fila. De forma predeterminada, la lista está separada por una coma.
Tenga en cuenta que existen restricciones sobre la duración de esta lista. Más sobre esto más adelante en el artículo.
Ejemplo:DISTINTO
Puedes usar DISTINCT
para eliminar duplicados (para que los registros duplicados se conviertan en un solo registro).
Ejemplo:
SELECT GROUP_CONCAT(DISTINCT TaskName) FROM Tasks;
Resultado:
+--------------------------------------------------------+ | GROUP_CONCAT(DISTINCT TaskName) | +--------------------------------------------------------+ | Do garden,Feed cats,Paint roof,Relax,Take dog for walk | +--------------------------------------------------------+
Entonces, en este caso, "Alimentar a los gatos" solo aparece una vez, mientras que en el ejemplo anterior aparecía dos veces.
Ejemplo:ORDENAR POR
Puedes usar ORDER BY
para ordenar los resultados por una columna dada.
Ejemplo:
SELECT GROUP_CONCAT(DISTINCT TaskName ORDER BY TaskName DESC) FROM Tasks;
Resultado:
+--------------------------------------------------------+ | GROUP_CONCAT(DISTINCT TaskName ORDER BY TaskName DESC) | +--------------------------------------------------------+ | Take dog for walk,Relax,Paint roof,Feed cats,Do garden | +--------------------------------------------------------+
Así que en este caso uso DESC
para especificar que debe estar en orden descendente. El valor alternativo (y predeterminado) es ASC
para ascender.
Ejemplo:especificar un delimitador
De forma predeterminada, la lista es una lista separada por comas. Sin embargo, puede especificar un delimitador de su elección si es necesario.
Para hacer esto, use SEPARATOR
seguido del valor literal de la cadena que debe insertarse entre los valores del grupo.
Ejemplo:
SELECT GROUP_CONCAT(DISTINCT TaskName SEPARATOR ' + ') FROM Tasks;
Resultado:
+----------------------------------------------------------------+ | GROUP_CONCAT(DISTINCT TaskName SEPARATOR ' + ') | +----------------------------------------------------------------+ | Do garden + Feed cats + Paint roof + Relax + Take dog for walk | +----------------------------------------------------------------+
Ejemplo:combinar columnas
También puede concatenar columnas y proporcionar su propio separador proporcionando un valor literal de cadena.
Ejemplo:
SELECT GROUP_CONCAT(TaskId, ') ', TaskName SEPARATOR ' ') FROM Tasks;
Resultado:
+------------------------------------------------------------------------------------+ | GROUP_CONCAT(TaskId, ') ', TaskName SEPARATOR ' ') | +------------------------------------------------------------------------------------+ | 1) Do garden 2) Feed cats 3) Paint roof 4) Take dog for walk 5) Relax 6) Feed cats | +------------------------------------------------------------------------------------+
En este ejemplo, devolvemos tanto el TaskId
columna y el TaskName
columna, separados por un paréntesis de cierre y un espacio. También usamos el SEPARATOR
argumento para especificar que el delimitador que se utilizará entre cada fila (concatenada) debe ser un espacio (en lugar de la coma predeterminada).
Resultados agrupados
El GROUP_CONCAT()
La función puede ser útil para ocasiones en las que desea proporcionar una lista de resultados, agrupados por otra columna.
Por ejemplo, es posible que desee una lista de artistas, con cada artista seguido de una lista de álbumes que han lanzado.
Para demostrar esto, digamos que tenemos una base de datos con dos tablas; Artists
y Albums
. Hay una relación de uno a muchos entre estas tablas. Para cada artista, puede haber muchos álbumes.
Entonces, una consulta regular que une ambas tablas podría verse así:
USE Music; SELECT ar.ArtistName, al.AlbumName FROM Artists ar INNER JOIN Albums al ON ar.ArtistId = al.ArtistId;
Resultado:
+------------------------+--------------------------+ | ArtistName | AlbumName | +------------------------+--------------------------+ | Iron Maiden | Powerslave | | AC/DC | Powerage | | Jim Reeves | Singing Down the Lane | | Devin Townsend | Ziltoid the Omniscient | | Devin Townsend | Casualties of Cool | | Devin Townsend | Epicloud | | Iron Maiden | Somewhere in Time | | Iron Maiden | Piece of Mind | | Iron Maiden | Killers | | Iron Maiden | No Prayer for the Dying | | The Script | No Sound Without Silence | | Buddy Rich | Big Swing Face | | Michael Learns to Rock | Blue Night | | Michael Learns to Rock | Eternity | | Michael Learns to Rock | Scandinavia | | Tom Jones | Long Lost Suitcase | | Tom Jones | Praise and Blame | | Tom Jones | Along Came Jones | | Allan Holdsworth | All Night Wrong | | Allan Holdsworth | The Sixteen Men of Tain | +------------------------+--------------------------+
Como puede ver, al usar este formato, si un artista tiene más de un álbum, ese artista aparece varias veces, una vez por cada álbum.
Podríamos modificar esta consulta para que cada artista aparezca solo una vez. Si un artista tiene más de un álbum, todos los álbumes se muestran en un solo campo dentro de una lista separada por comas. Podemos hacer esto gracias al GROUP_CONCAT()
función.
Ejemplo:
USE Music; SELECT ar.ArtistName, GROUP_CONCAT(al.AlbumName) FROM Artists ar INNER JOIN Albums al ON ar.ArtistId = al.ArtistId GROUP BY ArtistName;
Resultado:
+------------------------+----------------------------------------------------------------------------+ | ArtistName | GROUP_CONCAT(al.AlbumName) | +------------------------+----------------------------------------------------------------------------+ | AC/DC | Powerage | | Allan Holdsworth | All Night Wrong,The Sixteen Men of Tain | | Buddy Rich | Big Swing Face | | Devin Townsend | Epicloud,Ziltoid the Omniscient,Casualties of Cool | | Iron Maiden | Somewhere in Time,Piece of Mind,Powerslave,Killers,No Prayer for the Dying | | Jim Reeves | Singing Down the Lane | | Michael Learns to Rock | Eternity,Scandinavia,Blue Night | | The Script | No Sound Without Silence | | Tom Jones | Long Lost Suitcase,Praise and Blame,Along Came Jones | +------------------------+----------------------------------------------------------------------------+
¡Cuidado con la longitud!
Una cosa importante que debe tener en cuenta al usar GROUP_CONCAT()
es que el resultado se trunca a la longitud máxima proporcionada por group_concat_max_len
variable del sistema, que tiene un valor predeterminado de 1024
.
El valor de esta variable se puede establecer más alto usando la siguiente sintaxis:
SET [GLOBAL | SESSION] group_concat_max_len = val;
Donde val
es un entero sin signo.
Sin embargo, tenga en cuenta que la longitud máxima efectiva del valor de retorno está restringida por el valor de max_allowed_packet
.