2012-03-05 20 views
20

Próbuję udoskonalić kwerendy Obecnie używam:MySQL - Warunkowe liczyć się z GROUP BY

SELECT `puid`, 
     COUNT(DISTINCT `droid_v`) AS DROID, 
     COUNT(DISTINCT `sig_v`) AS sig, 
     SUM(NoExt) AS hits 
     FROM temp 
     GROUP BY `puid` 

I muszę dostać się tylko liczyć droid_v gdzie droid_V jest większa niż 0. Jest to można warunkować liczyć w ten sposób? W tej chwili, to jest liczenie wartości zerowych jako policzalny, a ja naprawdę nie można zmienić zera do null wartości.

Nie muszę znać wartości licznika dla droid_V = 0, wystarczy ją zliczyć, jeśli ma ona wartość większą od 0. Liczba ta będzie zawsze wynosić 0, 1, 2, 3 lub 4.


próbowałem:

SELECT `puid`, 
    COUNT(DISTINCT CASE WHEN `droid_v` > 0 THEN 1 END) AS DROID, 
    COUNT(DISTINCT `sig_v`) AS sig, 
    SUM(`NoExt`) AS hits 
    FROM temp 
    GROUP BY `puid` 

Ale to daje wynik binarny (0 lub 1) nie hrabia spodziewam.

Przykład wyjściowy =

puid   DROID sig  hits 
No PUID   1  1  252 
x-fmt/92  1  5  1008 

przewiduje Wydajność:

puid   DROID sig  hits 
No PUID   1  1  252 
x-fmt/92  3  5  1008 

dane próbki:

id;puid;droid_v;sig_v;speed;Ext;NoExt;tally 


1;"No PUID";"3";"v13";"SLOW";"0";"63";"63" 
2;"x-fmt/92";"3";"v13";"SLOW";"63";"0";"63" 
3;"x-fmt/92";"3";"v37";"SLOW";"63";"63";"126" 
4;"x-fmt/92";"3";"v45";"SLOW";"63";"63";"126" 
5;"x-fmt/92";"3";"v49";"SLOW";"63";"63";"126" 
6;"x-fmt/92";"3";"v50";"SLOW";"63";"63";"126" 
7;"x-fmt/92";"5";"v13";"SLOW";"63";"0";"63" 
8;"No PUID";"5";"v13";"SLOW";"0";"63";"63" 
9;"x-fmt/92";"5";"v37";"SLOW";"63";"63";"126" 
10;"x-fmt/92";"5";"v45";"SLOW";"63";"63";"126" 
11;"x-fmt/92";"5";"v49";"SLOW";"63";"63";"126" 
12;"x-fmt/92";"5";"v50";"SLOW";"63";"63";"126" 
13;"No PUID";"6";"v13";"FAST";"0";"63";"63" 
14;"x-fmt/92";"6";"v13";"SLOW";"63";"0";"63" 
15;"No PUID";"6";"v13";"SLOW";"0";"63";"63" 
16;"x-fmt/92";"6";"v13";"FAST";"63";"0";"63" 
17;"x-fmt/92";"6";"v37";"SLOW";"63";"63";"126" 
18;"x-fmt/92";"6";"v37";"FAST";"63";"63";"126" 
19;"x-fmt/92";"6";"v45";"FAST";"63";"63";"126" 
20;"x-fmt/92";"6";"v45";"SLOW";"63";"63";"126" 
21;"x-fmt/92";"6";"v49";"FAST";"63";"63";"126" 
22;"x-fmt/92";"6";"v49";"SLOW";"63";"63";"126" 
23;"x-fmt/92";"6";"v50";"FAST";"63";"63";"126" 
24;"x-fmt/92";"6";"v50";"SLOW";"63";"63";"126" 
+0

czy możesz dodać klauzulę "WHERE"? –

+0

z podanego przykładu, jaki jest twój oczekiwany wynik? –

Odpowiedz

26

Jeśli droid_v może być tylko 0, 1, 2, 3 lub 4, to COUNT (DISTINCT) nigdy nie zwróci więcej niż 5, ponieważ istnieje tylko pięć możliwych wartości. Czy tego chcesz? Jeśli tak, to spróbuj tego:

SELECT puid, COUNT(DISTINCT CASE WHEN droid_v > 0 THEN droid_v ELSE 0 END) - 1 AS droid /* -1 for the case where droid_v is 0 */ 
    , COUNT(DISTINCT sig_v) AS sig 
    , SUM(NoExt) AS hits 

Update: Ups, przepraszam, powyższe jest nie tak jak nie może byćzero. Powinno być:

SELECT puid, COUNT(DISTINCT CASE WHEN droid_v > 0 THEN droid_v END) AS droid 

Jeśli, z drugiej strony, chcesz zliczenie wszystkich wierszy, gdzie droid_v> 0, to myślę, że chcesz to:

SELECT puid, SUM(CASE WHEN droid_v > 0 THEN 1 ELSE 0 END) AS droid 
    , COUNT(DISTINCT sig_v) AS sig 
    , SUM(NoExt) AS hits 

nadzieję, że to pomaga.

+0

To jest ten, który odkładałem przed zmianą i próbowałem rozgryźć, co jest nie tak. Masz rację, to nie jest zero. Dziękuję za Twój czas. – Jay

7
SELECT 
    `puid`, 
    COUNT(DISTINCT CASE WHEN `droid_v` > 0 THEN `droid_v` END) AS DROID, 
    COUNT(DISTINCT `sig_v`) AS sig, 
    SUM(NoExt) AS hits 
+0

Hej, dzięki za sugestię, zredagowałem pytanie, aby odpowiedzieć na twój pomysł. – Jay

+0

Moja początkowa odpowiedź była błędna pomimo jasnego pytania. Zobacz poprawioną odpowiedź. –

+0

To działa zgodnie z oczekiwaniami. Dziękuję za poprawkę. – Jay

1

dodać do zapytania

WHERE droid_v > 0 
+0

Dziękuję za obejrzenie - ale to się nie udało. – Jay

3

Jest to najprostsze rozwiązanie mogę myśleć:

SELECT puid, 
SUM(droid_v > 0) AS DROID, 
COUNT(DISTINCT sig_v) AS sig, 
SUM(`NoExt`) AS hits 
FROM t 
GROUP BY puid 

Jednak nie jest jasne, czy chcesz liczyć odrębny czy nie.Jeśli chcesz policzyć odrębne wartości, wówczas:

SELECT puid, 
COUNT(if(droid_v > 0, droid_v, null)) AS DROID, 
COUNT(DISTINCT sig_v) AS sig, 
SUM(`NoExt`) AS hits 
FROM t 
GROUP BY puid 
+0

Dziękuję za spojrzenie - jest blisko, ale traci on tę szczególną funkcję, której potrzebuję (przepraszam, jeśli nie wyjaśniłem) – Jay

5

Wystarczy użyć sumę

więc jeśli chcesz coś grupowej to sprawdzić

select city, sum(case when gender = 'male' then 1 else 0 end) as male, 
sum(case when gender = 'female' then 1 else 0 end) as female 
from person 
group by city 

proste jak to: D