2016-01-05 10 views
20

Ho una tabella di MySQL come:È possibile raggruppare le righe in questo modo usando MySQL?

ID, USER, PARAM, VAL 
-------------------- 
1 | 1 | NAME | ADAM 
2 | 1 | AGE | 15 
3 | 2 | NAME | EVA 
4 | 2 | AGE | 16 
5 | 3 | NAME | CRISS 
6 | 3 | AGE | 14 

E io sono curioso di sapere se v'è una domanda che mi avrebbe dato qualcosa di simile a:

1 | ADAM | 15 
2 | EVE | 16 
3 | CRISS| 14 

Finora sto solo usando il seguito interrogare e raggruppare i record in un ciclo.

SELECT * FROM table WHERE PARAM ='NAME' OR PARAM = 'AGE' 

Ho provato ad usare GROUP ma senza successo.

+6

Perché hai strutturato la tabella in questo modo? –

+0

Perché non creare una tabella con: id, utente, nome, età – SuperDJ

+0

Poiché ogni utente ha parametri diversi - circa 20 e tale valore può essere facilmente modificato in futuro. In questo modo è molto più semplice aggiungere qualcosa senza la tabella ALTER. Ho solo bisogno di ottenere NAME e ETI attraverso una query. –

risposta

5

Si potrebbe fare una query del genere:

SELECT t1.user, 
     (
      SELECT val FROM tab1 t2 
      WHERE t2.user = t1.user 
      AND t2.param = 'Name' 
     ) name, 
     (
      SELECT val FROM tab1 t2 
      WHERE t2.user = t1.user 
      AND t2.param = 'Age' 
     ) age 
    FROM tab1 t1 
    GROUP BY user 

Un'altra possibilità è group_concat, ma poi hai tutti i valori di ascoltare in una colonna.

SELECT user, group_concat(param, ':', val) 
    FROM tab1 
    GROUP BY user 
15

Usa si uniscono nella stessa tabella:

SELECT a.USER user_id, a.VAL user_name, b.VAL user_age 
FROM `table` a 
INNER JOIN `table` b ON a.USER = b.USER 
WHERE a.PARAM = 'NAME' 
AND b.PARAM = 'AGE' 

Risultato:

user_id  user_name user_age 
1   ADAM  15 
2   EVA   16 
3   CRISS  14 
+2

Questo è un approccio migliore rispetto a max/group by. –

+2

@SalmanA perché? AFAIK è peggio. Prova a utilizzarlo con più di 1 o 2 valori per ottenere, è necessario un join per ogni nuova colonna. – edc65

3

Ciao io replicare il problema nel mio esempio db, Prova questa ricerca:

SELECT t1.USER,VAL,(SELECT VAL AS AGE FROM table1 where USER = t1.USER AND PARAM = 'AGE') as AGE 
    FROM table1 t1 
    WHERE param = 'NAME' 

o usa unirsi al tuo tavolo:

SELECT a.USER, a.VAL, b.VAL 
FROM table1 t1 
INNER JOIN table1 t2 
ON t1.USER = t2.USER 
WHERE t1.PARAM = 'NAME' 
AND t2.PARAM = 'AGE' 

sostituire tabella1 con il nome della tabella.

8

è possibile generare la vista del perno utilizzando la tecnica più comunemente usato come

select 
user, 
max(case when param = 'NAME' then val end) as name, 
max(case when param = 'AGE' then val end) as age 
from mytable 
group by user 
9

Non c'è alcuna necessità di utilizzare JOIN. Prova questo:

SELECT USER, 
     MAX(CASE PARAM WHEN 'NAME' THEN VAL ELSE NULL END) AS NAME, 
     MAX(CASE PARAM WHEN 'AGE' THEN VAL ELSE 0 END) AS AGE 
FROM test 
GROUP BY USER; 
+0

Questo è efficiente e l'ho usato qualche volta, ad esempio nella trasformazione dei dati per ETL. Puoi renderlo più breve e più leggibile rimuovendo il 'ELSE NULL' (e pensando a readable, aggiungi alcune newline) – edc65

+1

Ho usato entrambi lo stile di query per risolvere questo problema e posso dire che questo è sia più veloce che, in la mia opinione, più leggibile, soprattutto quando hai molti attributi utente da verificare. – Jupotter

+0

Il 'ELSE NULL' è inutile, ma il' ELSE 0' potrebbe essere chiaramente sbagliato in alcuni casi. Ora vota per @Abhik Chakraborty – edc65

Problemi correlati