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.

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.


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.


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

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.


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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.