2011-03-07 48 views
2

請你幫我建立一個查詢。我有一個表如下來框架成本效益的查詢

Id   Info_Id     Type 
1    2        2 
2    6        2 
3    5        3 
4    8        3 
5    2        3 
6    2        2 
7    5        2 
8    8        2 
9    5        2 
10    8        2 
11    8        2 
12    5        3 
13    6        3 
14    8        3 

查詢需要被框住,以便按「Info_Id」進行分組。

我需要如下輸出如:

Info_Id CountOfRec  Type2 Type3 
2    3   2    1 
5    4   2    2 
6    2   1    1 
8    5   3    2 

我嘗試如下,但我不是能夠得到高效輸出

select Info_Id, count(Id)as CountOfRec, 
(select count(Id)from tbl_TypeInfo where Info_Id = 5 AND Type = 2) as Type2, 
(select count(Id)from tbl_ TypeInfo where Info_Id = 5 AND Type = 3) as Type3 
from tbl_TypeInfo 
where Info_Id = 5 
group by Info_Id 

輸出是這樣的,

Info_Id CountOfRec  Type2 Type3 
5    4        2    2 

(我必須爲每個「Info_id」循環才能獲得所需的OP,有一千條記錄nd其耗時)

我想從表中突出顯示的輸出。我已經構建的查詢效率不高,並且會有很好的解決方案,可以幫助我解決這個問題。

回答

2

可以使用CASE表達只能算行特定類型:

SELECT Info_Id, 
    COUNT(*) AS CountOfRec, 
    COUNT(CASE WHEN Type = 2 THEN 1 ELSE NULL END) AS Type2 
    COUNT(CASE WHEN Type = 3 THEN 1 ELSE NULL END) AS Type3 
FROM tbl_TypeInfo 
GROUP BY Info_Id 

添加WHERE Info_Id = 5檢索只有一個特定ID的結果。

更新:按照意見,如果你不存儲ID的表,你需要你的(..)列表變成一個虛擬的「表」:

SELECT vt.id, 
    COUNT(*) AS CountOfRec, 
    COUNT(CASE WHEN Type = 2 THEN 1 ELSE NULL END) AS Type2, 
    COUNT(CASE WHEN Type = 3 THEN 1 ELSE NULL END) AS Type3 
FROM (
    SELECT 1 id 
    UNION SELECT 2 
    UNION SELECT 3 
    UNION SELECT 5 
    UNION SELECT 8 
) AS vt LEFT JOIN tbl_TypeInfo ON vt.id = tbl_TypeInfo.Info_Id 
GROUP BY vt.id 
+0

太棒了!非常感謝它的正常工作。 – 2011-03-07 08:32:10

+0

我想爲Info_Id顯示計數爲零,而Info_Id不存在於上表中,例如:Info_Id像1,3。我怎麼能實現這個PLZ。 – 2011-03-08 08:54:54

+0

@ fairy-g是否有另一張桌子可以放置** all ** info_id's?否則無法知道不存在的值。 – 2011-03-08 09:02:13

2

您可以使用SQL Server的PIVOT運營商

SELECT Info_ID 
     , CountOfRec = [2] + [3] 
     , Type2 = [2] 
     , Type3 = [3] 
FROM (  
      SELECT * 
      FROM (   
        SELECT * 
        FROM tbl_TypeInfo 
        ) s 
      PIVOT (COUNT(Id) FOR Type IN ([2], [3])) pvt 
     ) q 

測試

;WITH tbl_TypeInfo AS (
    SELECT [Id] = 1, [Info_Id] = 2, [Type] = 2 
    UNION ALL SELECT 2, 6, 2 
    UNION ALL SELECT 3, 5, 3 
    UNION ALL SELECT 4, 8, 3 
    UNION ALL SELECT 5, 2, 3 
    UNION ALL SELECT 6, 2, 2 
    UNION ALL SELECT 7, 5, 2 
    UNION ALL SELECT 8, 8, 2 
    UNION ALL SELECT 9, 5, 2 
    UNION ALL SELECT 1, 8, 2 
    UNION ALL SELECT 1, 8, 2 
    UNION ALL SELECT 1, 5, 3 
    UNION ALL SELECT 1, 6, 3 
    UNION ALL SELECT 1, 8, 3 
) 
SELECT Info_ID 
     , CountOfRec = [2] + [3] 
     , Type2 = [2] 
     , Type3 = [3] 
FROM (  
      SELECT * 
      FROM (   
        SELECT * 
        FROM tbl_TypeInfo 
        ) s 
      PIVOT (COUNT(Id) FOR Type IN ([2], [3])) pvt 
     ) q 
+0

謝謝列文。我不太熟悉'數據透視',但它似乎很好的工作。 – 2011-03-07 08:37:29

+0

@GayaMani,在這種情況下,我相信'CASE'方法是最易讀的解決方案,但是您可能會從中取走某些東西。 – 2011-03-07 08:43:01

+0

感謝您的正確支點有助於分組所有列。我正在與它合作。 – 2011-03-08 08:57:40

0

這有點瘋狂,但如果類型永遠,永遠 2和第3,這可以threated作爲一個公式,其中count(type2)+count(type3)=count(*)2*count(type2)+3*count(type3)=sum(*),所以你可以以類似

SELECT 3*c-s as Type2Count, s-2*c as Type3Count 
FROM (SELECT COUNT(*) as C, SUM(Type) as S 
     FROM tbl_TypeInfo 
     WHERE Info_Id = 5) SourceTable 

這將閃電般快速,但是,這是非常可破的! 如果有的話,類型會改變,或者類型被添加,這是行不通的。