2012-12-27 15 views
59

Chcę policzyć liczbę odrębnych elementów w kolumnie z zastrzeżeniem pewnych warunkach, na przykład, jeśli tabela jest tak:COUNT DISTINCT z warunkami

tag | entryID 
----+--------- 
foo | 0 
foo | 0 
bar | 3 

Jeśli chcę policzyć odrębną znaczniki jako "liczba znaczników" i policzyć liczbę odrębnych znaczników z identyfikatorem wpisu> 0 jako "dodatnią liczbę znaczników" w tej samej tabeli, co mam zrobić?

Teraz liczę od dwóch różnych tabel, w których w drugiej tabeli wybrałem tylko te wiersze z identyfikatorem entryID większym niż zero. Myślę, że powinien istnieć bardziej zwarty sposób rozwiązania tego problemu.

Odpowiedz

148

Można spróbować to:

select 
    count(distinct tag) as tag_count, 
    count(distinct (case when entryId > 0 then tag end)) as positive_tag_count 
from 
    your_table_name; 

Pierwszy count(distinct...) jest łatwe. Druga, wygląda nieco skomplikowana, jest w rzeczywistości taka sama jak pierwsza, z wyjątkiem tego, że używasz klauzuli case...when. W klauzuli case...when filtrowane są tylko wartości dodatnie. Zero lub wartości ujemne będą wynosić null i nie będą uwzględniane w zliczeniu.

Trzeba tu zwrócić uwagę, że można to zrobić, czytając tabelę jeden raz. Kiedy wydaje się, że musisz przeczytać ten sam stół dwa lub więcej razy, można to zrobić, czytając raz, w większości przypadków. W wyniku tego zadanie zostanie zakończone znacznie szybciej przy mniejszej liczbie wejść/wyjść.

+1

Ale czy wartość positive_tag_count również będzie inna? – derekhh

+0

Edytowane zapytanie nadal nie rozwiązuje problemu - czy to nie działa teraz na różnych wartościach pozycji początkowych, a nie odrębnych znacznikach? – BrianC

+0

To naprawdę sprytne rozwiązanie. – Luc

1

to może działać:

SELECT Count(tag) AS 'Tag Count' 
FROM Table 
GROUP BY tag 

i

SELECT Count(tag) AS 'Negative Tag Count' 
FROM Table 
WHERE entryID > 0 
GROUP BY tag 
0

ten może również pracować:

SELECT 
    COUNT(DISTINCT T.tag) as DistinctTag, 
    COUNT(DISTINCT T2.tag) as DistinctPositiveTag 
FROM Table T 
    LEFT JOIN Table T2 ON T.tag = T2.tag AND T.entryID = T2.entryID AND T2.entryID > 0 

Trzeba stan entryID w LEFT JOIN zamiast w klauzuli WHERE w celu upewnienia się, że wszystkie pozycje, które mają tylko wartość entryID wynoszącą 0, są poprawnie liczone w pierwszej DISTINCT.

+1

To zapytanie odczytuje tabelę dwa razy. Można to zrobić, czytając tabelę tylko raz. – ntalbs

1

Spróbuj następujące oświadczenie:

select distinct A.[Tag], 
    count(A.[Tag]) as TAG_COUNT, 
    (SELECT count(*) FROM [TagTbl] AS B WHERE A.[Tag]=B.[Tag] AND B.[ID]>0) 
    from [TagTbl] AS A GROUP BY A.[Tag] 

Pierwsze pole będzie tag drugi będzie cała liczba trzeci będzie liczyć na pozytywne.