2013-04-04 12 views
28

Ho la seguente tabella db e vorrei poter contare l'istanza di vendita di determinati prodotti per venditore.Colonne di conteggio MySQL su un valore specifico

|------------|------------|------------| 
|id   |user_id  |product_id | 
|------------|------------|------------| 
|1   |1   |2   | 
|2   |1   |4   | 
|3   |1   |2   | 
|4   |2   |1   | 
|------------|------------|------------| 

vorrei in grado di creare un set di risultati come il seguente;

|------------|-------------|------------|------------|------------| 
|user_id  |prod_1_count |prod_2_count|prod_3_count|prod_4_count| 
|------------|-------------|------------|------------|------------| 
|1   |0   |2   |0   |1   | 
|2   |1   |0   |0   |0   | 
|------------|-------------|------------|------------|------------| 

Sto creando i grafici con questi dati, e ancora una volta (come prima di oggi) non sono in grado di contare i totali delle colonne. Ho provato;

SELECT user_id, 
(SELECT count(product_id) FROM sales WHERE product_id = 1) AS prod_1_count, 
(SELECT count(product_id) FROM sales WHERE product_id = 2) AS prod_2_count, 
(SELECT count(product_id) FROM sales WHERE product_id = 3) AS prod_3_count, 
(SELECT count(product_id) FROM sales WHERE product_id = 4) AS prod_4_count 
FROM sales GROUP BY user_id; 

Posso capire perché questo non funziona, perché per ogni parentesi selezionare l'user_id non corrisponde al user_id esterna nella principale SELECT.

Qualcuno può darmi una mano qui?

ringrazia

risposta

62

È possibile farlo utilizzando SUM e CASE:

select user_id, 
    sum(case when product_id = 1 then 1 else 0 end) as prod_1_count, 
    sum(case when product_id = 2 then 1 else 0 end) as prod_2_count, 
    sum(case when product_id = 3 then 1 else 0 end) as prod_3_count, 
    sum(case when product_id = 4 then 1 else 0 end) as prod_4_count 
from your_table 
group by user_id 
+0

Grazie Ike, questa è stata la soluzione più veloce di tutte. Grazie :) –

+2

Non puoi semplicemente fare 'sum (product_id = 1)'? 'product_id = 1' è un'espressione booleana; restituirà naturalmente 1 o 0 senza il caso di commutazione. – mpen

+1

@ Mark sì che funzionerebbe pure, e potrebbe essere nominalmente più veloce, ma trovo la soluzione come scritta per essere più leggibile. –

1

vedere se questo funziona:

SELECT a.user_id, 
(SELECT count(b.product_id) FROM sales b WHERE b.product_id = 1 AND a.user_id = b.user_id) AS prod_1_count, 
(SELECT count(b.product_id) FROM sales b WHERE b.product_id = 2 AND a.user_id = b.user_id) AS prod_2_count, 
(SELECT count(b.product_id) FROM sales b WHERE b.product_id = 3 AND a.user_id = b.user_id) AS prod_3_count, 
(SELECT count(b.product_id) FROM sales b WHERE b.product_id = 4 AND a.user_id = b.user_id) AS prod_4_count 
FROM sales a GROUP BY a.user_id; 

applausi. n.b. potrebbero esserci modi leggermente migliori per ottenere il risultato equivalente.

+2

grazie, questa soluzione ha funzionato, ma ci sono voluti un paio di secondi. La soluzione di Ike è stata molto veloce al confronto, ma grazie comunque per la tua risposta @ d'alar'cop –

14

Si sta tentando di perno i dati. MySQL non ha una funzione di perno in modo dovrete utilizzare una funzione di aggregazione con un'espressione CASE:

select user_id, 
    count(case when product_id = 1 then product_id end) as prod_1_count, 
    count(case when product_id = 2 then product_id end) as prod_2_count, 
    count(case when product_id = 3 then product_id end) as prod_3_count, 
    count(case when product_id = 4 then product_id end) as prod_4_count 
from sales 
group by user_id; 

Vedi SQL Fiddle with Demo

+1

Vorrei poter dare questo 1.000 frecce in su. Pivoting appena cliccato. – ghukill

Problemi correlati