COUNT DISTINCT z CONDITIONS


104

Chcę policzyć liczbę różnych pozycji w kolumnie podlegającej pewnym warunkom, na przykład jeśli tabela wygląda następująco:

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

Jeśli chcę policzyć liczbę różnych tagów jako „liczbę tagów” ​​i policzyć liczbę różnych tagów o identyfikatorze pozycji> 0 jako „dodatnią liczbę tagów” ​​w tej samej tabeli, co powinienem zrobić?

Liczę teraz z dwóch różnych tabel, w których w drugiej tabeli wybrałem tylko te wiersze, które mają identyfikator wpisu większy niż zero. Myślę, że powinien istnieć bardziej zwarty sposób rozwiązania tego problemu.

Odpowiedzi:


258

Możesz spróbować tego:

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

Pierwsza count(distinct...)jest łatwa. Drugi, wygląda na nieco skomplikowany, jest w rzeczywistości taki sam jak pierwszy, z wyjątkiem tego, że używasz case...whenklauzuli. W case...whenklauzuli filtrujesz tylko wartości dodatnie. Zera lub wartości ujemne zostaną ocenione jako nulli nie zostaną uwzględnione w zliczaniu.

Należy tu zauważyć, że można to zrobić, czytając raz tabelę. Kiedy wydaje się, że musisz przeczytać tę samą tabelę dwa razy lub więcej, w rzeczywistości można to zrobić, czytając raz, przez większość czasu. W rezultacie zakończy zadanie znacznie szybciej przy mniejszej liczbie operacji we / wy.


2
Ale czy pozytywne_tag_count również będzie różne?
derekhh

Edytowane zapytanie nadal nie rozwiązuje problemu - czy nie działa to teraz na odrębnych wartościach entryId zamiast odrębnych tagów?
BrianC,

To naprawdę sprytne rozwiązanie.
Luc

Mam wiele kolumn w moim odrębnym (przykładowa liczba (odrębny tag, data)). Czy istnieje sposób na umieszczenie wielu kolumn w klauzuli then. Jeśli po prostu zrobię tag, data wyrzuca wyjątek parsowania
Crusaderpyro

@Crusaderpyro To wykracza poza zakres pierwotnego pytania. W tym celu stworzyłbym nowe pytanie.
ntalbs

2

Wypróbuj następujące stwierdzenie:

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 tagiem, drugie będzie całkowitą liczbą, a trzecie będzie liczbą dodatnich.


1

To może zadział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

Może to również działać:

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

Potrzebujesz warunku entryID w lewym złączeniu, a nie w klauzuli where, aby upewnić się, że wszystkie elementy, które mają tylko identyfikator wpisu równy 0, zostaną poprawnie policzone w pierwszym DISTINCT.


1
To zapytanie dwukrotnie odczytuje tabelę. Można to zrobić, czytając tabelę tylko raz.
ntalbs

0

Kod zlicza unikalną / odrębną kombinację tagu i identyfikatora wpisu, gdy [Entry Id]> 0

select count(distinct(concat(tag,entryId)))
from customers
where id>0

Na wyjściu wyświetli liczbę unikalnych wartości Mam nadzieję, że to pomoże

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.