Posso concatenare più righe MySQL in un unico campo?

Usando MySQL , posso fare qualcosa come:

 SELECT hobbies FROM peoples_hobbies WHERE person_id = 5; 

La mia uscita:

 shopping fishing coding 

ma invece voglio solo 1 riga, 1 colonna:

Uscita prevista:

 shopping, fishing, coding 

Il motivo è che sto selezionando più valori da più tabelle e, dopo tutti i join, ho molte più righe di quelle che vorrei.

Ho cercato una funzione su MySQL Doc e non sembra che le funzioni CONCAT o CONCAT_WS accettino i set di risultati, quindi qualcuno qui sa come fare?

Puoi utilizzare GROUP_CONCAT :

 SELECT person_id, GROUP_CONCAT(hobbies SEPARATOR ', ') FROM peoples_hobbies GROUP BY person_id 

Come Ludwig ha affermato nel suo commento, è ansible aggiungere l’operatore DISTINCT per evitare duplicati:

 SELECT person_id, GROUP_CONCAT(DISTINCT hobbies SEPARATOR ', ') FROM peoples_hobbies GROUP BY person_id 

Come Jan ha dichiarato nel loro commento, puoi anche ordinare i valori prima di implodere usando ORDER BY :

 SELECT person_id, GROUP_CONCAT(hobbies ORDER BY hobbies ASC SEPARATOR ', ') FROM peoples_hobbies GROUP BY person_id 

Come Dag ha dichiarato nel suo commento, c’è un limite di 1024 byte sul risultato. Per risolvere questo, eseguire questa query prima della query:

 SET group_concat_max_len = 2048 

Certo, puoi cambiare 2048 base alle tue esigenze. Per calcolare e assegnare il valore:

 SET group_concat_max_len = CAST( (SELECT SUM(LENGTH(hobbies)) + COUNT(*) * LENGTH(', ') FROM peoples_hobbies GROUP BY person_id) AS UNSIGNED ) 

GROUP_CONCAT un’occhiata a GROUP_CONCAT se la tua versione di MySQL (4.1) lo supporta. Vedi la documentazione per maggiori dettagli.

Assomiglierebbe a qualcosa:

  SELECT GROUP_CONCAT(hobbies SEPARATOR ', ') FROM peoples_hobbies WHERE person_id = 5 GROUP BY 'all'; 

Sintassi alternativa per concatenare più righe singole

ATTENZIONE: questo post ti farà venire fame.

Dato:

Mi sono ritrovato a voler selezionare più righe, singole righe, anziché un gruppo, e concatenare su un determinato campo.

Supponiamo che tu abbia una tabella di ID prodotto e i loro nomi e prezzi:

 +------------+--------------------+-------+ | product_id | name | price | +------------+--------------------+-------+ | 13 | Double Double | 5 | | 14 | Neapolitan Shake | 2 | | 15 | Animal Style Fries | 3 | | 16 | Root Beer | 2 | | 17 | Lame T-Shirt | 15 | +------------+--------------------+-------+ 

Poi hai qualche ajax di fantasia che elenca questi cuccioli come caselle di controllo.

L’utente affamato-ippopotamo seleziona 13, 15, 16 . Nessun dessert per lei oggi …

Trova:

Un modo per riassumere l’ordine dell’utente in una riga, con mysql puro.

Soluzione:

Utilizza GROUP_CONCAT con la clausola IN :

 mysql> SELECT GROUP_CONCAT(name SEPARATOR ' + ') AS order_summary FROM product WHERE product_id IN (13, 15, 16); 

Quali uscite:

 +------------------------------------------------+ | order_summary | +------------------------------------------------+ | Double Double + Animal Style Fries + Root Beer | +------------------------------------------------+ 

Soluzione bonus:

Se vuoi anche il prezzo totale, lancia in SUM() :

 mysql> SELECT GROUP_CONCAT(name SEPARATOR ' + ') AS order_summary, SUM(price) AS total FROM product WHERE product_id IN (13, 15, 16); +------------------------------------------------+-------+ | order_summary | total | +------------------------------------------------+-------+ | Double Double + Animal Style Fries + Root Beer | 10 | +------------------------------------------------+-------+ 

PS: Mi scuso se non hai un In-N-Out nelle vicinanze …

È ansible modificare la lunghezza massima del valore GROUP_CONCAT impostando il parametro group_concat_max_len .

Vedi i dettagli nella documentazione di MySQL .

Esiste una funzione GROUP Aggregate, GROUP_CONCAT .

Nel mio caso ho avuto una riga di Id, ed era necessario convertirla in char, altrimenti il ​​risultato è stato codificato in formato binario:

 SELECT CAST(GROUP_CONCAT(field SEPARATOR ',') AS CHAR) FROM table 

Utilizzare la variabile di sessione MySQL (5.6.13) e l’operatore di assegnazione come segue

 SELECT @logmsg := CONCAT_ws(',',@logmsg,items) FROM temp_SplitFields a; 

allora puoi ottenere

 test1,test11 

Ho avuto una query più complicata e ho scoperto che dovevo utilizzare GROUP_CONCAT in una query esterna per farlo funzionare:

Query originale:

 SELECT DISTINCT userID FROM event GROUP BY userID HAVING count(distinct(cohort))=2); 

implosa:

 SELECT GROUP_CONCAT(sub.userID SEPARATOR ', ') FROM (SELECT DISTINCT userID FROM event GROUP BY userID HAVING count(distinct(cohort))=2) as sub; 

Spero che questo possa aiutare qualcuno.

Prova questo:

 DECLARE @Hobbies NVARCHAR(200) = ' ' SELECT @Hobbies = @Hobbies + hobbies + ',' FROM peoples_hobbies WHERE person_id = 5;