Resultados de MySQL como lista separada por comas

129

Necesito ejecutar una consulta como:

SELECT p.id, p.name, 
       (SELECT name 
          FROM sites s 
         WHERE s.id = p.site_id) AS site_list
  FROM publications p

Pero me gustaría que la sub-selección devuelva una lista separada por comas, en lugar de una columna de datos. ¿Es esto posible, y si es así, cómo?

Glen Solsberry
fuente

Respuestas:

250

Puede usar GROUP_CONCAT para realizar eso, por ejemplo, algo como

SELECT p.id, p.name, GROUP_CONCAT(s.name) AS site_list
FROM sites s
INNER JOIN publications p ON(s.id = p.site_id)
GROUP BY p.id, p.name;
Paul Dixon
fuente
10
Además, tenga en cuenta que si está usando PHPMyAdmin y desea generar una lista delimitada por comas en la página, use GROUP_CONCAT(CAST(s.name AS CHAR))o de lo contrario simplemente devolverá algo completamente inútil [BLOB - 20 Bytes].
devios1
3
La intención está bien y MySQL lo permitirá, pero tenga cuidado (generalmente) con el uso de GROUP BY. Los elementos en la lista de selección deben ser agregados válidos en el contexto de la cláusula GROUP BY. En este caso, p.name no es estrictamente válido. Cualquier base de datos que cumpla con el estándar SQL tratará esto como un error. Para este caso, use MAX (p.name) en la lista de selección o agregue p.name a la cláusula GROUP BY. Dado que Paul probablemente significa que p.id representa una clave primaria o única, agregar p.name a la cláusula GROUP BY no tendrá ningún impacto en el resultado final.
Jon Armstrong - Xgc
Tenga en cuenta que puede que tenga que establecer la duración máxima de la sesión por stackoverflow.com/questions/2567000/…
sobelito
¡Muchas gracias! ¡Me ayudaste mucho!
André Agostinho
11

En lugar de usar group concat()puedes usar soloconcat()

Select concat(Col1, ',', Col2) as Foo_Bar from Table1;

editar esto solo funciona en mySQL; Oracle concat solo acepta dos argumentos. En Oracle puede usar algo como select col1 || ',' || col2 || ',' || col3 como foobar de table1; en el servidor sql usaría + en lugar de tuberías.

Robert Quinn
fuente
2
Esto no debería funcionar en el caso de GROUP BY, mientras que GROUP_CONCAT () concatenará el contenido de una sola columna
Aram Paronikyan,
5

Ahora solo me encontré con esta situación y encontré algunas características más interesantes GROUP_CONCAT. Espero que estos detalles te hagan sentir interesante.

simple GROUP_CONCAT

SELECT GROUP_CONCAT(TaskName) 
FROM Tasks;

Resultado:

+------------------------------------------------------------------+
| GROUP_CONCAT(TaskName)                                           |
+------------------------------------------------------------------+
| Do garden,Feed cats,Paint roof,Take dog for walk,Relax,Feed cats |
+------------------------------------------------------------------+

GROUP_CONCAT con DISTINCT

SELECT GROUP_CONCAT(TaskName) 
FROM Tasks;

Resultado:

+------------------------------------------------------------------+
| GROUP_CONCAT(TaskName)                                           |
+------------------------------------------------------------------+
| Do garden,Feed cats,Paint roof,Take dog for walk,Relax,Feed cats |
+------------------------------------------------------------------+

GROUP_CONCAT con DISTINCT y ORDER BY

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 |
+--------------------------------------------------------+

GROUP_CONCAT con DISTINCT y SEPARATOR

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 |
+----------------------------------------------------------------+

GROUP_CONCAT y columnas combinadas

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 |
+------------------------------------------------------------------------------------+

GROUP_CONCAT y resultados agrupados Suponga que los siguientes son los resultados antes de usarGROUP_CONCAT

+------------------------+--------------------------+
| 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  |
+------------------------+--------------------------+
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                       |
+------------------------+----------------------------------------------------------------------------+
Ganesa Vijayakumar
fuente
3

En mi caso, tengo que concatenar todo el número de cuenta de una persona cuyo número de teléfono móvil es único. Así que he usado la siguiente consulta para lograr eso.

SELECT GROUP_CONCAT(AccountsNo) as Accounts FROM `tblaccounts` GROUP BY MobileNumber

El resultado de la consulta está abajo:

Accounts
93348001,97530801,93348001,97530801
89663501
62630701
6227895144840002
60070021
60070020
60070019
60070018
60070017
60070016
60070015
Vignesh Chinnaiyan
fuente