2012-12-27 104 views
59

我要计数不同的项目数列中受到了一定的条件,例如,如果表是这样的:COUNT DISTINCT与条件

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

如果我要计算不同数标记为“标记计数”,并在同一个表中将条目ID> 0的不同标记的数目计为“正确标记计数”,我该怎么办?

我现在从两个不同的表格中,在第二个表格中,我只选择了entryID大于零的那些行。我认为应该有更紧凑的方法来解决这个问题。

回答

148

你可以试试这个:

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

第一count(distinct...)容易。 第二个,看起来有点复杂,实际上和第一个一样,除了你使用case...when条款。在case...when子句中,仅过滤正值。零点或负值应为null,不包括在计数中。

这里需要注意的一件事是,这可以通过读取表格一次来完成。看起来你必须两次或多次阅读同一张表,实际上可以通过在大多数时间阅读一次来完成。因此,它将以更少的I/O更快地完成任务。

+1

但是,那么positive_tag_count也会有区别吗? – derekhh

+0

编辑的查询仍然不能解决问题 - 是不是现在工作在不同的entryId值而不是不同的标签? – BrianC

+0

这是一个非常聪明的解决方案。 – Luc

1

这可能工作:

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

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

这也可能工作:

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 

您需要在左侧ENTRYID条件联接,而不是在where子句中以确保任何只有entryID为0的项目才能在第一个DISTINCT中正确计数。

+1

该查询读取表格两次。它可以通过只读表一次来完成。 – ntalbs

1

试试下面的语句:

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] 

的第一场将是标签上的第二个将是整个计数的三分之一将是正面的计数。