En éste artículo intento explicar el objetivo de esta instrucción no demasiado conocida el group_concat(). La verdad es que en mi trabajo cotidiano me ha salvado el pellejo. Podéis encontrar una descripción exacta en la documentación de MySQL (Funciones del Group By).
Imaginemos que tenemos una tabla típica de teléfonos de clientes, con unos campos típicos (id_cliente, teléfono, país, ...). Ésta tabla tiene la particularidad: si un cliente tiene más de un teléfono, tendrá un registro por cada teléfono, con la información extra que la tabla marque (el país, móvil o fijo... vaya, lo que se nos ocurra). Para un cliente dado, podríamos tener los siguientes registros:
| id_cliente |
telefono |
pais |
fijo |
| 123 |
696001122 |
ES |
0 |
| 123 |
932345678 |
ES |
1 |
| 123 |
998745621 |
FR |
1 |
| 123 |
696001122 |
FR |
0 |
Como vemos, tenemos que el mismo cliente tiene teléfonos en dos países diferentes, y en cada país tiene dos números, uno fijo y otro móvil. Imaginemos que ésto se da varias veces con varios clientes. Un día alguien busca la ficha del cliente 123 por el flamante buscador de clientes que busca por número de teléfonos y esperando sacar el movil francés le sale el movil español... mmm... qué buscador más malo... sólo te muestra la primera coincidencia... pero para el caso ya sirve.
Pero el que lo ha buscado es un accionista general, que se cabrea como una mona y manda al informático de turno saber qué pasa. El informático le explica que el buscador que compró a una empresa externa era una caca, y que además hay números de teléfono iguales en diferentes países. El jefe lo más probable es que diga "Y cuantos clientes tenemos en ésta situación?"... Y aquí entra nuestra nueva función.
Nosotros somos muy chulos y decimos "Bah, ésto con un count(*) y un group by lo tenemos solucionado":
SQL:
-
SELECT id_cliente, count(*) FROM telefonos GROUP BY id_cliente
| id_cliente |
count(*) |
| 123 |
4 |
Pero ésto te da el número de teléfonos que tiene cada cliente... necesitamos saber los clientes que tienen teléfonos iguales en diferentes paises. Podemos probar otra:
SQL:
-
SELECT id_cliente, pais, count(telefono) FROM telefonos GROUP BY id_cliente, pais
| id_cliente |
pais |
count(telefono) |
| 123 |
ES |
2 |
| 123 |
FR |
2 |
Ésto nos dará un resultado por cada país en el que el cliente tenga un teléfono, pero lo que queremos es que esté todo en un mismo registro, para luego poderlos contar... mmm... la cosa se complica más... porque además sólo queremos los que tengan teléfonos iguales en diferentes países.
Probaremos otra, ahora usando un having para indicar que sólo queremos los teléfonos que se repitan dos veces o más:
SQL:
-
SELECT id_cliente, pais, telefono, count(telefono) FROM telefonos GROUP BY id_cliente, telefono HAVING count(telefono)>=2
| id_cliente |
pais |
telefono |
count(telefono) |
| 123 |
ES |
696001122 |
2 |
Ésta ya se acerca más, pero curiosamente nos hace algo parecido a lo que ha hecho saltar las alarmas: sólo nos muestra el contenido del primer campo pais encontrado, el ES. Ahora sólo nos queda montarnos alguna forma para que muestre una concatenación de todos los paises en los que hay teléfonos coincidentes... ¿cómo lo hacemos? ¿usamos una join reflexiva para tener todos los registros a mano? uff...
No, usaremos el group_concat(), que concatena todos los registros afectados por los group by en un solo campo de salida:
SQL:
-
SELECT id_cliente, group_concat(pais), telefono, count(telefono) FROM telefonos GROUP BY id_cliente, telefono HAVING count(telefono)>=2
| id_cliente |
group_concat(pais) |
telefono |
count(telefono) |
| 123 |
ES,FR |
696001122 |
2 |
Mágicamente tenemos todos los países afectados por el problema dentro del mismo registro! Ahora ya podemos ir al jefe de turno a darle el resultado.
Escribe un Comentario