SQL Server:具有计数(*)的零值

SQL Server:具有计数(*)的零值,sql,sql-server,Sql,Sql Server,我有一个表@MemberAttribute MemberID AttributeID AttributeValue 1 1 False 1 2 True 2 1 False 2 2 True 3 1 False 3 2 False 我想按attributeID分组

我有一个表@MemberAttribute

MemberID AttributeID AttributeValue
1            1         False 
1            2         True 
2            1         False
2            2         True 
3            1         False
3            2         False
我想按attributeID分组,并获得值为True的属性数。但当某个特定属性的attributetype为false时,我希望它显示0。现在所有假值的属性ID都没有出现。 下面是sql查询

SELECT MA.AttributeID, GA.Name,
--COUNT(isNull(MA.AttributeID,0)) as AttributCount,
CASE WHEN COUNT(MA.AttributeID) > 0 THEN COUNT(MA.AttributeID) Else 0 END AS 'AttributCount'
--CASE WHEN COUNT(MA.AttributeID) < 0 THEN 0 Else COUNT(MA.AttributeID) END AS 'TOTAL Attributes'
from GroupAttribute GA
inner join   @MemberAttribute MA on GA.GroupAttributeID = MA.AttributeID
WHERE MA.AttributeValue = 'True'
GROUP BY MA.AttributeID,GA.Name
选择MA.AttributeID,GA.Name,
--计数(isNull(MA.AttributeID,0))作为AttributeCount,
当计数(MA.AttributeID)>0时,则计数(MA.AttributeID)否则0以“attributeCount”结束
--当计数(MA.AttributeID)<0时,则0个其他计数(MA.AttributeID)作为“总属性”结束
从组属性遗传算法
GA.GroupAttributeID=MA.AttributeID上的内部联接@MemberAttribute MA
其中MA.AttributeValue='True'
按MA.AttributeID、GA.Name分组
对于AttributeID=1,所有值均为=False。。。结果是这样的

AttributeID      Name      AttributeCount <br/>
2                Attr2        2 <br/>
AttributeID名称AttributeCount
2属性2
我想要

1                 Attr1      0  <br/>
1属性10

也在结果集中。

试试这个-注意,
中的1…然后是1 ELSE…
是一个任意的非空值-它可以是“fred”或12345-它不是空值是重要的部分

SELECT MA.AttributeID, GA.Name,
COUNT(CASE WHEN MA.AttributeValue = 'True' THEN 1 ELSE NULL END) AS 'AttributeCount'
from GroupAttribute GA
inner join   @MemberAttribute MA on GA.GroupAttributeID = MA.AttributeID
GROUP BY MA.AttributeID,GA.Name
…更直观一些(谢谢Ken)-注意这里1和0很重要

SELECT MA.AttributeID, GA.Name,
SUM(CASE WHEN MA.AttributeValue = 'True' THEN 1 ELSE 0 END) AS 'AttributeCount'
from GroupAttribute GA
inner join   @MemberAttribute MA on GA.GroupAttributeID = MA.AttributeID
GROUP BY MA.AttributeID,GA.Name

经过一番挣扎之后,我想出了一个没有
CASE
表达式的美丽:

SELECT GA.GroupAttributeID AS AttributeID, GA.Name, 
       COUNT(MA.AttributeID) AS AttributeCount
FROM GroupAttribute AS GA 
LEFT OUTER JOIN @MemberAttribute AS MA 
  ON GA.GroupAttributeID = MA.AttributeID AND MA.AttributeValue = 'True'
GROUP BY GA.GroupAttributeID, GA.Name
这利用了这样一个事实,即如果特定的
AttributeID
没有“True”值,则由
左侧外部联接产生的
MA.AttributeID
将为
NULL
。传递到
COUNT()
NULL
值将导致
AttributeCount
为零。
左侧外部联接
还确保在
AttributeID
行的结果集中出现计数为零的行

此查询的假设是所有组属性都表示在
@MemberAttribute
表变量中。如果没有,则将有计数为零的行,表示缺少的组属性。如果这是不需要的,可以添加
WHERE
子句来过滤它们,从而使查询复杂化。如果是这样的话,威尔的解决方案将更加实用

执行计划与Will的第一个解决方案相比,包含的步骤少了一步(计算标量)。它确实使用了
左外部联接
而不是
内部联接
,但是,对于这个简单的示例,这两种方法实际上是相同的。如果将表变量转换为一个相当大的表,那么看看这两个解决方案是如何伸缩的将是一件有趣的事情

威尔解决方案的实际计划包括
COUNT()

我的实际计划:


我认为,要使其工作,您需要将
COUNT
更改为
SUM
并将
ELSE NULL
更改为
ELSE 0
。@Ken-不需要-聚合函数忽略NULL,COUNT(something)返回非NULL值的计数。我试过了,效果很好。这就是说,也许用1和0求和会更直观。@Ken-答案已更新,将您建议的更改作为一个合适的选择。@Will:好的观点。我发现
更直观。我只是发表了评论,没有投反对票;因为你的第一句评论完全正确,这是一件好事。:)@Will:+1表示您的答案(特别是呈现两个选项)。不错。:)没有投反对票,但对于所提出的问题来说,这似乎过于复杂了。你真的认为这是一个可行的替代方案(以及增加索引的额外开销)吗?我同意,这对于所问的问题来说太复杂了。然而,我只是展示了一个替代方案,如果将解决方案外推到一个实际问题,该问题涉及的不仅仅是一个带有几个值的表变量。。。而且,这是一个没有案例的替代方案……啊,明白了。因此,如果我问如何添加1+1,而不是解释如何添加,你想解释反向波兰符号计算器的电路,以防我将来需要它吗?@Ken,lol!你让我努力简化。现在,看看我改进的解决方案,避免使用CASE,甚至没有WHERE子句。我对你的想法很感兴趣:)@Michael..对不起,忘了把它标记为答案。。。如果可能的话,你能解释为什么将条件MA.AttributeValue='True'从where子句移动到LEFT join会产生如此大的差异。。。如果我把这个条件放回Where子句中,它不会给我想要的sol。这是我以前得到的相同结果。。。但是只要把这个语句移到左连接,就会有很大的不同…你能解释一下吗?