Wyniki MySQL w postaci listy oddzielonej przecinkami

129

Muszę uruchomić zapytanie takie jak:

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

Ale chciałbym, aby sub-select zwrócił listę oddzieloną przecinkami zamiast kolumny danych. Czy to w ogóle możliwe, a jeśli tak, to w jaki sposób?

Glen Solsberry
źródło

Odpowiedzi:

250

Możesz użyć GROUP_CONCAT, aby to zrobić, np. Coś takiego

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
źródło
10
Zwróć również uwagę, że jeśli używasz PHPMyAdmin i chcesz wypisać listę rozdzielaną przecinkami na stronę, użyj GROUP_CONCAT(CAST(s.name AS CHAR))lub po prostu zwróci coś całkowicie bezużytecznego, jak [BLOB - 20 Bytes].
devios1
3
Zamiar jest w porządku i MySQL na to pozwoli, ale bądź ostrożny (ogólnie) przy używaniu GROUP BY. Pozycje na liście wyboru muszą być poprawnymi agregatami w kontekście klauzuli GROUP BY. W tym przypadku p.name nie jest ściśle poprawna. Każda baza danych zgodna ze standardem SQL potraktuje to jako błąd. W tym przypadku użyj MAX (p.name) z listy wyboru lub dodaj p.name do klauzuli GROUP BY. Ponieważ Paul prawdopodobnie oznacza p.id do reprezentowania klucza podstawowego lub unikalnego, dodanie p.name do klauzuli GROUP BY nie będzie miało wpływu na ostateczny wynik.
Jon Armstrong - Xgc
Pamiętaj, że może być konieczne ustawienie maksymalnej długości sesji na stackoverflow.com/questions/2567000/ ...
sobelito
Dziękuję bardzo! Bardzo mi pomogłeś!
André Agostinho
11

Zamiast używać group concat(), możesz użyć justconcat()

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

edycja działa tylko w mySQL; Oracle concat akceptuje tylko dwa argumenty. W Oracle możesz użyć czegoś takiego jak select col1 || ',' || col2 || ',' || col3 jako foobar z tabeli1; na serwerze sql użyłbyś + zamiast potoków.

Robert Quinn
źródło
2
To nie powinno działać w przypadku GROUP BY, podczas gdy GROUP_CONCAT () połączy zawartość jednej kolumny
Aram Paronikyan
5

Dopiero teraz natknąłem się na tę sytuację i znalazłem kilka ciekawszych funkcji GROUP_CONCAT. Mam nadzieję, że te szczegóły sprawią, że poczujesz się interesująco.

prosty GROUP_CONCAT

SELECT GROUP_CONCAT(TaskName) 
FROM Tasks;

Wynik:

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

GROUP_CONCAT z DISTINCT

SELECT GROUP_CONCAT(TaskName) 
FROM Tasks;

Wynik:

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

GROUP_CONCAT z DISTINCT i ORDER BY

SELECT GROUP_CONCAT(DISTINCT TaskName ORDER BY TaskName DESC) 
FROM Tasks;

Wynik:

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

GROUP_CONCAT z DISTINCT i SEPARATOR

SELECT GROUP_CONCAT(DISTINCT TaskName SEPARATOR ' + ') 
FROM Tasks;

Wynik:

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

GROUP_CONCAT i łączenie kolumn

SELECT GROUP_CONCAT(TaskId, ') ', TaskName SEPARATOR ' ') 
FROM Tasks;

Wynik:

+------------------------------------------------------------------------------------+
| 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 i pogrupowane wyniki Załóżmy, że przed użyciem przedstawiono następujące wynikiGROUP_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;

Wynik:

+------------------------+----------------------------------------------------------------------------+
| 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
źródło
3

W moim przypadku muszę połączyć cały numer konta osoby, której numer telefonu komórkowego jest unikalny. Więc użyłem następującego zapytania, aby to osiągnąć.

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

Wynik zapytania jest poniżej:

Accounts
93348001,97530801,93348001,97530801
89663501
62630701
6227895144840002
60070021
60070020
60070019
60070018
60070017
60070016
60070015
Vignesh Chinnaiyan
źródło