2011-03-07 49 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 

这将闪电般快速,但是,这是非常可破的! 如果有的话,类型会改变,或者类型被添加,这是行不通的。