COUNT DISTINCT con CONDIZIONI


104

Voglio contare il numero di elementi distinti in una colonna soggetta a una certa condizione, ad esempio se la tabella è così:

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

Se voglio contare il numero di tag distinti come "conteggio tag" e contare il numero di tag distinti con ID di entrata> 0 come "conteggio tag positivo" nella stessa tabella, cosa devo fare?

Ora sto contando da due diverse tabelle in cui nella seconda tabella ho selezionato solo quelle righe con entryID maggiore di zero. Penso che dovrebbe esserci un modo più compatto per risolvere questo problema.

Risposte:


258

Puoi provare questo:

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

Il primo count(distinct...)è facile. Il secondo, sembra un po 'complesso, è in realtà lo stesso del primo, tranne per il fatto che usi la case...whenclausola. Nella case...whenclausola filtri solo i valori positivi. Zeri o valori negativi verranno valutati come nulle non verranno inclusi nel conteggio.

Una cosa da notare qui è che questo può essere fatto leggendo la tabella una volta. Quando sembra che devi leggere la stessa tabella due o più volte, in realtà può essere fatto leggendo una volta, nella maggior parte delle volte. Di conseguenza, terminerà l'attività molto più velocemente con meno I / O.


2
Ma allora anche positive_tag_count sarà distinto?
derekhh

La query modificata continua a non risolvere il problema: non funziona ora su valori entryId distinti anziché tag distinti?
BrianC

Questa è una soluzione davvero intelligente.
Luc

Ho più colonne nel mio distinto (numero di esempio (tag distinto, data)). C'è un modo per avere più colonne nella clausola then. Se faccio solo un tag, la data genera un'eccezione di analisi
Crusaderpyro

@Crusaderpyro Questo va oltre lo scopo della domanda originale. Creerei una nuova domanda per questo.
ntalbs

2

Prova la seguente dichiarazione:

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]

Il primo campo sarà il tag il secondo sarà il conteggio completo il terzo sarà il conteggio positivo.


1

Questo potrebbe funzionare:

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

Questo può funzionare anche:

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

Hai bisogno della condizione entryID nel join sinistro piuttosto che in una clausola where per assicurarti che tutti gli elementi che hanno solo un entryID di 0 vengano contati correttamente nel primo DISTINCT.


1
Questa query legge la tabella due volte. Può essere fatto leggendo la tabella una sola volta.
ntalbs

0

Il codice conta la combinazione univoca / distinta di tag e ID voce quando [ID ingresso]> 0

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

Nell'output verrà visualizzato il conteggio dei valori univoci Spero che questo aiuti

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.