2013-04-04 18 views
28

Mam następującą tabelę db i chciałbym móc policzyć wystąpienie sprzedaży niektórych produktów na jednego sprzedawcę.Liczba kolumn MySQL o określonej wartości

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

Chciałbym utworzyć zestaw wyników, jak poniżej;

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

Tworzę wykresy z tymi danymi i jeszcze raz (tak jak dzisiaj) nie jestem w stanie zliczyć sum kolumn. Próbowałem;

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; 

mogę zrozumieć, dlaczego to nie działa, ponieważ za każdy nawias SELECT user_id nie pasuje do zewnętrznego user_id w głównym SELECT.

Czy ktoś może mi pomóc?

dziękuje

Odpowiedz

62

Można to zrobić za pomocą SUM i 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

Dzięki Ike, to był najszybszy ze wszystkich rozwiązań. Dziękuję :) –

+2

Nie możesz po prostu zrobić 'sum (product_id = 1)'? 'product_id = 1' jest wyrażeniem boolowskim; to naturalnie zwróci 1 lub 0 bez skrzynki przełącznika. – mpen

+1

@ Mark tak, że również będzie działać, i może być nominalnie szybszy, ale uważam, że rozwiązanie jest napisane jako bardziej czytelne. –

1

sprawdzić, czy to działa:

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; 

Cheers. n.b. mogą istnieć nieco ładniejsze sposoby na uzyskanie równoważnego wyniku.

+2

dzięki, to rozwiązanie nie działa, ale to trwało kilka sekund. Rozwiązanie Ike było bardzo szybkie w porównaniu, ale dziękuję za odpowiedź. @ D'alar'cop –

14

Próbujesz przegubu danych. MySQL nie posiada funkcję pivot, więc trzeba będzie użyć funkcji zagregowanego z wyrażeniem 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; 

Zobacz SQL Fiddle with Demo

+1

Chciałbym móc dać 1000 strzał w górę. Obracanie tylko kliknięte. – ghukill

Powiązane problemy