Posso concatenare più righe MySQL in un campo?
-
07-07-2019 - |
Domanda
Usando MySQL
, posso fare qualcosa del tipo:
SELECT hobbies FROM peoples_hobbies WHERE person_id = 5;
Il mio output:
shopping
fishing
coding
ma invece voglio solo 1 riga, 1 colonna:
Output previsto:
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 set di risultati, quindi qualcuno qui sa come farlo?
Soluzione
Puoi utilizzare group_concat
:
SELECT person_id, GROUP_CONCAT(hobbies SEPARATOR ', ')
FROM peoples_hobbies
GROUP BY person_id;
Come ha affermato Ludwig in il suo commento, è possibile aggiungere l'operatore DISTINCT
per evitare duplicati:
SELECT person_id, GROUP_CONCAT(DISTINCT hobbies SEPARATOR ', ')
FROM peoples_hobbies
GROUP BY person_id;
Come ha affermato Jan in il loro commento, puoi anche ordinare i valori prima di imploderlo usando ORDER BY
:
SELECT person_id, GROUP_CONCAT(hobbies ORDER BY hobbies ASC SEPARATOR ', ')
FROM peoples_hobbies
GROUP BY person_id;
Come ha affermato Dag in il suo commento, esiste un limite di 1024 byte sul risultato. Per risolvere il problema, esegui questa query prima della query:
SET group_concat_max_len = 2048;
Ovviamente puoi cambiare 2048
in 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
);
Altri suggerimenti
Dai un'occhiata a GROUP_CONCAT
se la tua versione MySQL (4.1) la supporta. Vedi la documentazione per ulteriori informazioni i dettagli.
Sarebbe simile a:
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.
Data:
Mi sono ritrovato a voler selezionare più righe singole — anziché un gruppo — e concatenarmi in 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 |
+------------+--------------------+-------+
Quindi hai un po 'di fantasia ajax che elenca questi cuccioli come caselle di controllo.
Il tuo utente affamato di ippopotamo seleziona 13, 15, 16
. Nessun dessert per lei oggi ...
Trova:
Un modo per riassumere l'ordine del tuo utente in una riga, con puro mysql.
Soluzione:
Usa 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 output:
+------------------------------------------------+
| order_summary |
+------------------------------------------------+
| Double Double + Animal Style Fries + Root Beer |
+------------------------------------------------+
Soluzione bonus:
Se vuoi anche il prezzo totale, aggiungi 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 .. .
Puoi 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 avevo una riga di ID ed era necessario lanciarlo su char, altrimenti il ??risultato è stato codificato in formato binario:
SELECT CAST(GROUP_CONCAT(field SEPARATOR ',') AS CHAR) FROM table
Utilizza la variabile di sessione MySQL (5.6.13) e l'operatore di assegnazione come il seguente
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 usare GROUP_CONCAT
in una query esterna per farlo funzionare:
Query originale:
SELECT DISTINCT userID
FROM event GROUP BY userID
HAVING count(distinct(cohort))=2);
implose:
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;
Per qualcuno che guarda qui come usare GROUP_CONCAT
con la subquery - pubblicando questo esempio
SELECT i.*,
(SELECT GROUP_CONCAT(userid) FROM favourites f WHERE f.itemid = i.id) AS idlist
FROM items i
WHERE i.id = $someid
Quindi GROUP_CONCAT
deve essere usato all'interno della sottoquery, non racchiudendolo.
abbiamo due modi per concatenare le colonne in MySql
select concat(hobbies) as `Hobbies` from people_hobbies where 1
o
select group_concat(hobbies) as `Hobbies` from people_hobbies where 1