MariaDB tiene un GROUP_CONCAT()
función que nos permite devolver columnas de una consulta como una lista delimitada.
Sintaxis
La sintaxis es así:
GROUP_CONCAT([DISTINCT] expr [,expr ...]
[ORDER BY {unsigned_integer | col_name | expr}
[ASC | DESC] [,col_name ...]]
[SEPARATOR str_val]
[LIMIT {[offset,] row_count | row_count OFFSET offset}])
Ejemplo
Supongamos que ejecutamos la siguiente consulta:
SELECT PetName
FROM Pets;
Y obtenemos el siguiente resultado:
+---------+ | PetName | +---------+ | Fluffy | | Fetch | | Scratch | | Wag | | Tweet | | Fluffy | | Bark | | Meow | +---------+ 8 rows in set (0.001 sec)
Podemos usar GROUP_CONCAT()
para devolver todas esas filas como una lista delimitada.
Para lograr esto, todo lo que necesitamos hacer es pasar el PetName
columna como argumento para GROUP_CONCAT()
función:
SELECT GROUP_CONCAT(PetName)
FROM Pets;
Resultado:
+-------------------------------------------------+ | GROUP_CONCAT(PetName) | +-------------------------------------------------+ | Fluffy,Fetch,Scratch,Wag,Tweet,Fluffy,Bark,Meow | +-------------------------------------------------+ 1 row in set (0.003 sec)
Pedidos
Podemos usar el ORDER BY
cláusula para ordenar la salida de esta función:
SELECT GROUP_CONCAT(PetName ORDER BY PetName DESC)
FROM Pets;
Resultado:
Wag,Tweet,Scratch,Meow,Fluffy,Fluffy,Fetch,Bark
Tenga en cuenta que esto solo ordena la salida de GROUP_CONCAT()
función:es completamente independiente de cualquier orden aplicado a SELECT
declaración en sí.
Limitación de la salida
Podemos usar el LIMIT
cláusula para limitar cuántos elementos se incluyen en la lista:
SELECT GROUP_CONCAT(PetName LIMIT 3)
FROM Pets;
Resultado:
Fluffy,Fetch,Scratch
Cualquier orden se aplica antes del LIMIT
cláusula:
SELECT GROUP_CONCAT(PetName ORDER BY PetName DESC LIMIT 3)
FROM Pets;
Resultado:
Wag,Tweet,Scratch
Tenga en cuenta que el LIMIT
La cláusula solo es compatible con MariaDB 10.3.3.
El DISTINCT
Cláusula
Podemos usar el DISTINCT
cláusula para devolver valores únicos. En otras palabras, si hay valores duplicados, solo se devuelve una ocurrencia:
SELECT GROUP_CONCAT(DISTINCT PetName ORDER BY PetName ASC)
FROM Pets;
Resultado:
Bark,Fetch,Fluffy,Meow,Scratch,Tweet,Wag
En este caso, Fluffy
solo aparece una vez. Cuando lo ejecutamos sin DISTINCT
cláusula, Fluffy
aparece dos veces.
Cambiar el separador
De forma predeterminada, la lista utiliza la coma como delimitador. Pero podemos cambiar esto si queremos:
SELECT GROUP_CONCAT(PetName SEPARATOR '-')
FROM Pets;
Resultado:
Fluffy-Fetch-Scratch-Wag-Tweet-Fluffy-Bark-Meow
Incluso podemos usar una cadena vacía para eliminar todos los separadores (para que los valores se concatenen):
SELECT GROUP_CONCAT(PetName SEPARATOR '')
FROM Pets;
Y obtenemos el siguiente resultado:
FluffyFetchScratchWagTweetFluffyBarkMeow
Resultados de consultas agrupados
Podemos incluir GROUP_CONCAT()
en una consulta con un GROUP BY
cláusula para lograr un resultado como este:
SELECT
PetTypeId,
GROUP_CONCAT(PetName ORDER BY PetName ASC)
FROM Pets
GROUP BY PetTypeId
ORDER BY PetTypeId;
Resultado:
+-----------+--------------------------------------------+ | PetTypeId | GROUP_CONCAT(PetName ORDER BY PetName ASC) | +-----------+--------------------------------------------+ | 1 | Tweet | | 2 | Fluffy,Meow,Scratch | | 3 | Bark,Fetch,Fluffy,Wag | +-----------+--------------------------------------------+
En mi base de datos, los nombres reales de los tipos de mascotas están en otra tabla llamada PetTypes
. Por lo tanto, podríamos ejecutar un INNER JOIN
en PetTypes
tabla para obtener los nombres reales de los tipos de mascotas:
SELECT
pt.PetType,
GROUP_CONCAT(p.PetName ORDER BY p.PetName ASC)
FROM Pets p
INNER JOIN PetTypes pt ON
p.PetTypeId = pt.PetTypeId
GROUP BY pt.PetType
ORDER BY pt.PetType ASC;
Resultado:
+---------+------------------------------------------------+ | PetType | GROUP_CONCAT(p.PetName ORDER BY p.PetName ASC) | +---------+------------------------------------------------+ | Bird | Tweet | | Cat | Fluffy,Meow,Scratch | | Dog | Bark,Fetch,Fluffy,Wag | +---------+------------------------------------------------+
Limitaciones de longitud
La longitud máxima devuelta en bytes está determinada por group_concat_max_len
variable del sistema del servidor, que por defecto es 1M (en MariaDB 10.2.4 y versiones posteriores) o 1K (en MariaDB 10.2.3 y versiones anteriores). Si group_concat_max_len
es 512
o inferior, el tipo de retorno es VARBINARY
o VARCHAR
; de lo contrario, el tipo de retorno es BLOB
o TEXT
. La elección entre tipos binarios o no binarios depende de la entrada.
Puede verificar el valor actual de esta manera:
SHOW VARIABLES LIKE '%group_concat%';
La sintaxis para cambiar este valor es la siguiente:
SET [GLOBAL | SESSION] group_concat_max_len = val;
Donde val
es un entero sin signo.