2012-12-27 25 views
59

ich die Anzahl der verschiedenen Elemente in einer Spalte unter einer bestimmten Bedingung, beispielsweise zählen will, wenn die Tabelle ist wie folgt:COUNT DISTINCT mit BEDINGUNGEN

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

Wenn ich die Anzahl der unterschiedlichen zählen möge Tags als "tag count" und zählen die Anzahl der verschiedenen Tags mit der Eintrags-ID> 0 als "positive tag count" in der gleichen Tabelle, was soll ich tun?

Ich zähle jetzt von zwei verschiedenen Tabellen, wo ich in der zweiten Tabelle nur die Zeilen mit entryID größer als Null ausgewählt habe. Ich denke, es sollte einen kompakteren Weg geben, um dieses Problem zu lösen.

Antwort

148

Sie können dies versuchen:

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

Die erste count(distinct...) einfach ist. Die zweite, sieht etwas komplex aus, ist eigentlich die gleiche wie die erste, außer dass Sie case...when Klausel verwenden. In der Klausel case...when filtern Sie nur positive Werte. Nullen oder negative Werte wären null und sind nicht in der Zählung enthalten.

Eine Sache zu beachten ist hier, dass dies durch einmaliges Lesen der Tabelle getan werden kann. Wenn es so aussieht, als ob Sie die gleiche Tabelle zweimal oder öfter lesen müssen, können Sie dies tatsächlich tun, indem Sie in den meisten Fällen einmal lesen. Dadurch wird die Aufgabe mit weniger I/O viel schneller erledigt.

+1

Aber wird auch positive_tag_count eindeutig sein? – derekhh

+0

Die bearbeitete Abfrage löst das Problem immer noch nicht - funktioniert das jetzt nicht an eindeutigen entryId-Werten und nicht an eindeutigen Tags? – BrianC

+0

Dies ist eine wirklich clevere Lösung. – Luc

1

Diese Arbeit kann:

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

und

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

Dies kann auch arbeiten:

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 

Sie die entryID Zustand im linken müssen join und nicht in einer where-Klausel um sicherzustellen, dass alle Elemente, die nur eine entryID von 0 haben, in der ersten DISTINCT ordnungsgemäß gezählt werden.

+1

Diese Abfrage liest die Tabelle zweimal. Es kann getan werden, indem man die Tabelle nur einmal liest. – ntalbs

1

Versuchen Sie, die folgende Erklärung ab:

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] 

Das erste Feld wird der Tag sein, der zweite wird die ganze Zahl sein die dritte wird die positiven zählen sein.

Verwandte Themen