COUNT DISTINCT con CONDICIONES

104

Quiero contar el número de elementos distintos en una columna sujetos a una determinada condición, por ejemplo, si la tabla es así:

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

Si quiero contar el número de etiquetas distintas como "recuento de etiquetas" y contar el número de etiquetas distintas con ID de entrada> 0 como "recuento de etiquetas positivas" en la misma tabla, ¿qué debo hacer?

Ahora estoy contando desde dos tablas diferentes donde en la segunda tabla solo seleccioné aquellas filas con entryID mayor que cero. Creo que debería haber una forma más compacta de resolver este problema.

derekhh
fuente

Respuestas:

258

Puedes probar esto:

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

Lo primero count(distinct...)es sencillo. El segundo, parece algo complejo, en realidad es el mismo que el primero, excepto que usa una case...whencláusula. En la case...whencláusula, filtra solo valores positivos. Los ceros o valores negativos se evaluarán como nully no se incluirán en el recuento.

Una cosa a tener en cuenta aquí es que esto se puede hacer leyendo la tabla una vez. Cuando parece que tiene que leer la misma tabla dos o más veces, en realidad puede hacerlo leyendo una vez, la mayor parte del tiempo. Como resultado, terminará la tarea mucho más rápido con menos E / S.

ntalbs
fuente
2
Pero entonces, ¿Positive_tag_count también será distinto?
derekhh
La consulta editada aún no resuelve el problema. ¿No funciona ahora con valores de entryId distintos en lugar de etiquetas distintas?
BrianC
Esta es una solución realmente inteligente.
Luc
Tengo varias columnas en mi distinta (cuenta de ejemplo (etiqueta distinta, fecha)). ¿Hay alguna forma de tener varias columnas en la cláusula then? Si solo hago una etiqueta, la fecha arroja una excepción de análisis
Crusaderpyro
@Crusaderpyro Eso está más allá del alcance de la pregunta original. Crearía una nueva pregunta para eso.
ntalbs
2

Pruebe la siguiente declaración:

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]

El primer campo será la etiqueta, el segundo será el conteo completo y el tercero será el conteo de los positivos.

MJBLACKEND
fuente
1

Esto puede funcionar:

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

y

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

Esto también puede funcionar:

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

Necesita la condición entryID en la combinación izquierda en lugar de en una cláusula where para asegurarse de que cualquier elemento que solo tenga un entryID de 0 se cuente correctamente en el primer DISTINCT.

BrianC
fuente
1
Esta consulta lee la tabla dos veces. Se puede hacer leyendo la tabla solo una vez.
ntalbs
0

El código cuenta la combinación única / distinta de etiqueta e ID de entrada cuando [ID de entrada]> 0

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

En la salida mostrará el recuento de valores únicos Espero que esto ayude

Abhishek Gupta
fuente