2011-06-13 42 views
2

我有屬性ID表@MemberAttributeSQL服務器:零個值與COUNT(*)

MemberID AttributeID AttributeValue 
1   1   False 
1   2   True 
2   1   False 
2   2   True 
3   1   False 
3   2   False 

我想組,並得到其值爲True屬性的數量。但是當attributetype對於某個特定屬性爲false時,我希望它顯示0.現在,具有所有虛假值的attributeID不會顯示出來。 這裏是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 

FOR屬性Id = 1的所有值均爲=假...這樣的結果是這樣的

AttributeID  Name  AttributeCount <br/> 
2    Attr2  2 <br/> 

我想

1     Attr1  0 <br/> 

太結果集。

+0

感謝它指向了 – shazia 2011-06-14 16:12:26

回答

3

一些蠕動後,我想出了含有這種美是沒有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,所述MA.AttributeID從得到的將是NULL。傳遞到COUNT()NULL值將導致零值爲AttributeCountLEFT OUTER JOIN還確保行數將存在於AttributeID行的結果集中,計數爲零。

該查詢的假設是所有組屬性都在@MemberAttribute表變量中表示。如果不是,則會有零個計數的行表示那些不存在的組屬性。如果這是不希望的,可以添加WHERE子句將其過濾掉,這使查詢變得複雜。如果是這種情況,威爾的解決方案將更加實用。

執行計劃與Will的第一個解決方案相比較很好,包含少一個(Compute Scalar)步驟。它確實使用LEFT OUTER JOIN而不是INNER JOIN,但是,使這兩個方法在這個簡單示例中幾乎相同。取而代之的是,如果將表變量轉換爲相當大的表,那麼看看這兩種解決方案如何擴展會很有趣。

威爾對他的解決方案涉及COUNT()實際計劃:

enter image description here

我實際的計劃:

enter image description here

+0

沒有投票,但這似乎是非常複雜的問題。你是否認真地提出這個問題是一個可行的替代方案(以及額外的索引額外開銷)? – 2011-06-14 00:42:30

+0

我同意這個問題太複雜了。然而,我只是展示了一個替代方案,如果解決方案是外推到一個真正的世界問題涉及多個表變量與幾個值...此外,這是一個替代沒有CASE ... – 2011-06-14 00:58:26

+0

啊,明白了。所以,如果我問如何添加1 + 1,而不是解釋如何做,你想解釋逆波蘭記法計算器的電路,以防萬一我將來需要它? – 2011-06-14 02:36:20

4

試試這個 - 請注意,...THEN 1 ELSE ...中的1是一個任意的非NULL值 - 它可以是'fred'或12345 - 它不是NULL是重要的部分。

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 

...有點更直觀地(感謝肯) - 並注意這裏的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 
+0

您需要COUNT'改變'來'SUM '和'ELSE NULL'到'ELSE 0'這個工作,我想。 – 2011-06-13 23:17:41

+0

@Ken - 不需要 - 聚合函數忽略NULL,COUNT(something)返回非NULL值的計數。已經嘗試過,它工作正常。也就是說,可能SUM與1和0會更直觀。 – 2011-06-13 23:18:48

+0

@Ken - 答案已更新,以包含您建議的更改作爲一個體面的替代方案。 – 2011-06-13 23:23:02