COUNT DISTINCT avec CONDITIONS

104

Je veux compter le nombre d'éléments distincts dans une colonne soumise à une certaine condition, par exemple si le tableau est comme ceci:

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

Si je veux compter le nombre de balises distinctes comme "nombre de balises" et compter le nombre de balises distinctes avec un identifiant d'entrée> 0 comme "nombre de balises positives" dans le même tableau, que dois-je faire?

Je compte maintenant à partir de deux tables différentes où, dans la deuxième table, je n'ai sélectionné que les lignes avec entryID supérieur à zéro. Je pense qu'il devrait y avoir un moyen plus compact de résoudre ce problème.

derekhh
la source

Réponses:

258

Vous pouvez essayer ceci:

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

Le premier count(distinct...)est facile. Le second, semble assez complexe, est en fait le même que le premier, sauf que vous utilisez une case...whenclause. Dans la case...whenclause, vous filtrez uniquement les valeurs positives. Les zéros ou les valeurs négatives seront évalués comme nullet ne seront pas inclus dans le décompte.

Une chose à noter ici est que cela peut être fait en lisant le tableau une fois. Lorsqu'il semble que vous deviez lire le même tableau deux fois ou plus, cela peut en fait être fait en lisant une fois, la plupart du temps. En conséquence, il terminera la tâche beaucoup plus rapidement avec moins d'E / S.

ntalbs
la source
2
Mais alors positive_tag_count sera-t-il également distinct?
derekhh
La requête modifiée ne résout toujours pas le problème - cela ne fonctionne-t-il pas maintenant sur des valeurs entryId distinctes plutôt que sur des balises distinctes?
BrianC
C'est une solution vraiment intelligente.
Luc
J'ai plusieurs colonnes dans mon distinct (nombre d'exemples (balise distincte, date)). Existe-t-il un moyen d'avoir plusieurs colonnes dans la clause then. Si je viens de faire une balise, datez-la lève une exception d'analyse
Crusaderpyro
@Crusaderpyro Cela dépasse le cadre de la question initiale. Je créerais une nouvelle question pour cela.
ntalbs
2

Essayez la déclaration suivante:

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]

Le premier champ sera la balise, le second sera le nombre total, le troisième sera le nombre de positifs.

MJBLACKEND
la source
1

Cela peut fonctionner:

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

et

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

Cela peut également fonctionner:

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

Vous avez besoin de la condition entryID dans la jointure de gauche plutôt que dans une clause where pour vous assurer que tous les éléments qui n'ont qu'un entryID de 0 sont correctement comptés dans le premier DISTINCT.

BrianC
la source
1
Cette requête lit deux fois la table. Cela peut être fait en lisant le tableau une seule fois.
ntalbs
0

Le code compte la combinaison unique / distincte de balise et d'ID d'entrée lorsque [Entry Id]> 0

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

Dans la sortie, il affichera le nombre de valeurs uniques J'espère que cela aide

Abhishek Gupta
la source