COUNT DISTINCT com CONDITIONS

104

Quero contar o número de itens distintos em uma coluna sujeita a uma determinada condição, por exemplo, se a tabela for assim:

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

Se eu quiser contar o número de tags distintas como "contagem de tag" e contar o número de tags distintas com id de entrada> 0 como "contagem de tag positiva" na mesma tabela, o que devo fazer?

Agora estou contando a partir de duas tabelas diferentes onde, na segunda tabela, selecionei apenas as linhas com entryID maior que zero. Acho que deveria haver uma maneira mais compacta de resolver esse problema.

derekhh
fonte

Respostas:

258

Você pode tentar isto:

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

O primeiro count(distinct...)é fácil. O segundo, parece um tanto complexo, é na verdade o mesmo que o primeiro, exceto que você usa uma case...whencláusula. Na case...whencláusula, você filtra apenas valores positivos. Zeros ou valores negativos serão avaliados como nulle não serão incluídos na contagem.

Uma coisa a observar aqui é que isso pode ser feito lendo a tabela uma vez. Quando parece que você tem que ler a mesma tabela duas ou mais vezes, na verdade isso pode ser feito lendo uma vez, na maioria das vezes. Como resultado, ele terminará a tarefa muito mais rápido com menos E / S.

ntalbs
fonte
2
Mas, então, positive_tag_count também será distinto?
derekhh
A consulta editada ainda não resolve o problema - isso agora não está funcionando em valores entryId distintos em vez de tags distintas?
BrianC
Esta é uma solução realmente inteligente.
Luc de
Eu tenho várias colunas na minha (contagem de exemplo (marca distinta, data)). Existe uma maneira de ter várias colunas na cláusula then. Se eu apenas fizer uma tag, a data lançará uma exceção de análise
Crusaderpyro
@Crusaderpyro Isso está além do escopo da pergunta original. Eu criaria uma nova pergunta para isso.
ntalbs
2

Experimente a seguinte afirmação:

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]

O primeiro campo será a tag, o segundo será a contagem total e o terceiro será a contagem positiva.

MJBLACKEND
fonte
1

Isso pode funcionar:

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

e

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

Isso também pode 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

Você precisa da condição entryID na junção à esquerda, em vez de em uma cláusula where para garantir que todos os itens que tenham apenas um entryID 0 sejam contados corretamente no primeiro DISTINCT.

BrianC
fonte
1
Esta consulta lê a tabela duas vezes. Isso pode ser feito lendo a tabela apenas uma vez.
ntalbs
0

O código conta a combinação única / distinta de Tag e ID de entrada quando [ID de entrada]> 0

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

Na saída irá mostrar a contagem de valores únicos Espero que isso ajude

Abhishek Gupta
fonte