mysql - right - outer join




Posso concatenare più righe MySQL in un unico campo? (6)

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?


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


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

Vedi i dettagli nella GROUP_CONCAT .


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.


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

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, è possibile 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
);

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




group-concat