COUNT个包含关系和用户的多个表

时间:2016-09-28 13:00:30

标签: sql sql-server

我在SQL Server中有一组表需要依赖于每个表的特定计数标准,我遇到的问题是我需要将用户分组,这些用户包含在一个表中通过关系表映射到我需要依赖的表。

这是关系表

 Relationship    User    Work Item
 Analyst         1       IR1
 Analyst         2       IR2
 Analyst         2       IR3
 Analyst         1       IR4
 User            3       IR1
 Analyst         1       SR2
 Analyst         1       SR3
 Analyst         2       SR4

这是IR表(SR表是相同的)

 ID     Status
 IR1    Active
 IR2    Active
 IR3    Closed
 IR4    Active

这是用户表

 User     Name
 1        Dave
 2        Jim
 3        Karl

我需要的是下面的表格,只计算活动项目

 Name   IR Count  SR Count
 Dave   2         2
 Jim    1         1 

我现在似乎能够做的就是统计所有用户,无论状态如何,我认为这可能是由于左连接。我基本上有:

 Select u.name,
 count (ir),
 count (sr) from user u
 Inner join relationship r on r.user=u.user and r.relationship = 'Analyst'
 Left Join IR on r.workitem=ir.id and ir.Status = 'Active'
 Left Join SR on r.workitem=sr.id and sr.Status = 'Active'
 Group by u.name

我尽可能地简化了上述内容。这是实际查询:

 SELECT 
 u.DisplayName as Analyst, 
 u.BaseManagedEntityId as AUsername,
 COUNT(distinct i.Id_9A505725_E2F2_447F_271B_9B9F4F0D190C) AS 'Active Incidents',
 COUNT(distinct sr.Id_9A505725_E2F2_447F_271B_9B9F4F0D190C) as 'Active Service Requests',
 COUNT(distinct cr.Id_9A505725_E2F2_447F_271B_9B9F4F0D190C) as 'Active Change Requests',
 COUNT(distinct ma.Id_9A505725_E2F2_447F_271B_9B9F4F0D190C) as 'Active Manual Activities'
 FROM MTV_System$Domain$User u 
 INNER JOIN RelationshipView r ON r.TargetEntityId = u.BaseManagedEntityId AND r.RelationshipTypeId = '15E577A3-6BF9-6713-4EAC-BA5A5B7C4722'  AND  r.IsDeleted ='0'
 LEFT JOIN  MTV_System$WorkItem$Incident i ON r.SourceEntityId = i.BaseManagedEntityId AND (i.Status_785407A9_729D_3A74_A383_575DB0CD50ED != '2B8830B6-59F0-F574-9C2A-F4B4682F1681' AND i.Status_785407A9_729D_3A74_A383_575DB0CD50ED != 'BD0AE7C4-3315-2EB3-7933-82DFC482DBAF')
 LEFT JOIN MTV_System$WorkItem$ServiceRequest sr ON r.SourceEntityId = SR.BaseManagedEntityId AND (sr.Status_6DBB4A46_48F2_4D89_CBF6_215182E99E0F = '72B55E17-1C7D-B34C-53AE-F61F8732E425' OR sr.Status_6DBB4A46_48F2_4D89_CBF6_215182E99E0F = '59393F48-D85F-FA6D-2EBE-DCFF395D7ED1' OR sr.Status_6DBB4A46_48F2_4D89_CBF6_215182E99E0F = '05306BF5-A6B9-B5AD-326B-BA4E9724BF37')
 LEFT JOIN MTV_System$WorkItem$ChangeRequest cr on r.SourceEntityId = cr.BaseManagedEntityId AND (cr.Status_72C1BC70_443C_C96F_A624_A94F1C857138 = '6D6C64DD-07AC-AAF5-F812-6A7CCEB5154D' or cr.Status_72C1BC70_443C_C96F_A624_A94F1C857138 = 'DD6B0870-BCEA-1520-993D-9F1337E39D4D')
 LEFT JOIN MTV_System$WorkItem$Activity$ManualActivity MA on r.SourceEntityId = ma.BaseManagedEntityId AND (ma.Status_8895EC8D_2CBF_0D9D_E8EC_524DEFA00014 = '11FC3CEF-15E5-BCA4-DEE0-9C1155EC8D83' OR ma.Status_8895EC8D_2CBF_0D9D_E8EC_524DEFA00014 = 'D544258F-24DA-1CF3-C230-B057AAA66BED')

 GROUP BY u.DisplayName,u.BaseManagedEntityId
 Order by u.DisplayName

5 个答案:

答案 0 :(得分:1)

您的过度简化似乎已经从您的一些评论中丢失了您的问题。使用左连接将包括任何用户,即使他们没有其他一个表的计数。但是,如果您希望结果集仅包含至少包含1个事件和/或1个请求和/或1个更改请求的usres。等等,你可以过滤掉你在事件+请求+ ... = 0时删除的事情。或者你可以通过添加一个WHERE语句来过滤它们,这些语句说明并非所有其他表都是null与OR IS NOT NULL相同......

 SELECT 
 u.DisplayName as Analyst, 
 u.BaseManagedEntityId as AUsername,
 COUNT(distinct i.Id_9A505725_E2F2_447F_271B_9B9F4F0D190C) AS 'Active Incidents',
 COUNT(distinct sr.Id_9A505725_E2F2_447F_271B_9B9F4F0D190C) as 'Active Service Requests',
 COUNT(distinct cr.Id_9A505725_E2F2_447F_271B_9B9F4F0D190C) as 'Active Change Requests',
 COUNT(distinct ma.Id_9A505725_E2F2_447F_271B_9B9F4F0D190C) as 'Active Manual Activities'
 FROM
    MTV_System$Domain$User u 
    INNER JOIN RelationshipView r
    ON r.TargetEntityId = u.BaseManagedEntityId
    AND r.RelationshipTypeId = '15E577A3-6BF9-6713-4EAC-BA5A5B7C4722' 
    AND  r.IsDeleted ='0'
    LEFT JOIN  MTV_System$WorkItem$Incident i
    ON r.SourceEntityId = i.BaseManagedEntityId
    AND i.Status_785407A9_729D_3A74_A383_575DB0CD50ED NOT IN ('2B8830B6-59F0-F574-9C2A-F4B4682F1681','BD0AE7C4-3315-2EB3-7933-82DFC482DBAF')
    LEFT JOIN MTV_System$WorkItem$ServiceRequest sr
    ON r.SourceEntityId = SR.BaseManagedEntityId
    AND sr.Status_6DBB4A46_48F2_4D89_CBF6_215182E99E0F IN ('72B55E17-1C7D-B34C-53AE-F61F8732E425','59393F48-D85F-FA6D-2EBE-DCFF395D7ED1','05306BF5-A6B9-B5AD-326B-BA4E9724BF37')
    LEFT JOIN MTV_System$WorkItem$ChangeRequest cr
    ON r.SourceEntityId = cr.BaseManagedEntityId
    AND cr.Status_72C1BC70_443C_C96F_A624_A94F1C857138 IN ('6D6C64DD-07AC-AAF5-F812-6A7CCEB5154D','DD6B0870-BCEA-1520-993D-9F1337E39D4D')
    LEFT JOIN MTV_System$WorkItem$Activity$ManualActivity MA
    ON r.SourceEntityId = ma.BaseManagedEntityId
    AND ma.Status_8895EC8D_2CBF_0D9D_E8EC_524DEFA00014 IN ('11FC3CEF-15E5-BCA4-DEE0-9C1155EC8D83','D544258F-24DA-1CF3-C230-B057AAA66BED')
WHERE
    i.Id_9A505725_E2F2_447F_271B_9B9F4F0D190C IS NOT NULL
    OR sr.Id_9A505725_E2F2_447F_271B_9B9F4F0D190C IS NOT NULL
    OR cr.Id_9A505725_E2F2_447F_271B_9B9F4F0D190C IS NOT NULL
    OR ma.Id_9A505725_E2F2_447F_271B_9B9F4F0D190C IS NOT NULL
GROUP BY u.DisplayName,u.BaseManagedEntityId
 Order by u.DisplayName

在连接条件中注意IN和NOT IN的用户而不是所有时间的OR。

答案 1 :(得分:0)

问题是count()。相反,您需要count(distinct)

Select u.name,
       count(distinct ir),
       count(distinct sr)
from user u
. . .

这会在irsr值之间生成笛卡尔积。如果每组中都有较大的数字,那么在join之前聚合是一种更好的方法。

答案 2 :(得分:0)

尝试使用以下脚本。

SELECT u.name
  ,SUM(t1.[IR Count]) [IR Count]
  ,SUM(t2.[SR Count]) [SR Count]
FROM #user u
 INNER JOIN #relationship r on r.[user]=u.[user]and r.relationship = 'Analyst'
  CROSS APPLY (SELECT  COUNT(DISTINCT ID) [IR Count]
               FROM #IR ir WHERE r.workitem=ir.id and ir.Status = 'Active') t1
  CROSS APPLY (SELECT  COUNT(DISTINCT ID) [SR Count]
               FROM #SR sr WHERE r.workitem=sr.id and sr.Status = 'Active')t2
GROUP BY u.name

输出

enter image description here

如果SR表与IR表的SR表相同,则样本输出中的SR计数错误(SR3的状态因用户“dave”而关闭,因此将被忽略。)

答案 3 :(得分:0)

collect

答案 4 :(得分:0)

这是我提出的似乎基于实际表格

的工作原理
 SELECT 
 u.DisplayName as Analyst, 
 u.BaseManagedEntityId as AUsername,
 COUNT(distinct i.Id_9A505725_E2F2_447F_271B_9B9F4F0D190C) AS 'Active Incidents',
 COUNT(distinct sr.Id_9A505725_E2F2_447F_271B_9B9F4F0D190C) as 'Active Service Requests',
 COUNT(distinct cr.Id_9A505725_E2F2_447F_271B_9B9F4F0D190C) as 'Active Change Requests',
 COUNT(distinct ma.Id_9A505725_E2F2_447F_271B_9B9F4F0D190C) as 'Active Manual Activities'
 FROM MTV_System$Domain$User u 
  LEFT JOIN RelationshipView r ON r.TargetEntityId = u.BaseManagedEntityId AND r.RelationshipTypeId = '15E577A3-6BF9-6713-4EAC-BA5A5B7C4722'  AND  r.IsDeleted ='0'
  LEFT JOIN  MTV_System$WorkItem$Incident i ON r.SourceEntityId = i.BaseManagedEntityId
  LEFT JOIN MTV_System$WorkItem$ServiceRequest sr ON r.SourceEntityId = SR.BaseManagedEntityId
  LEFT JOIN MTV_System$WorkItem$ChangeRequest cr on r.SourceEntityId = cr.BaseManagedEntityId
 LEFT JOIN MTV_System$WorkItem$Activity$ManualActivity MA on r.SourceEntityId = ma.BaseManagedEntityId 
 Where (i.Status_785407A9_729D_3A74_A383_575DB0CD50ED != '2B8830B6-59F0-F574-9C2A-F4B4682F1681' AND i.Status_785407A9_729D_3A74_A383_575DB0CD50ED != 'BD0AE7C4-3315-2EB3-7933-82DFC482DBAF')
 OR (sr.Status_6DBB4A46_48F2_4D89_CBF6_215182E99E0F = '72B55E17-1C7D-B34C-53AE-F61F8732E425' OR sr.Status_6DBB4A46_48F2_4D89_CBF6_215182E99E0F = '59393F48-D85F-FA6D-2EBE-DCFF395D7ED1' OR sr.Status_6DBB4A46_48F2_4D89_CBF6_215182E99E0F = '05306BF5-A6B9-B5AD-326B-BA4E9724BF37')
 OR (cr.Status_72C1BC70_443C_C96F_A624_A94F1C857138 = '6D6C64DD-07AC-AAF5-F812-6A7CCEB5154D' or cr.Status_72C1BC70_443C_C96F_A624_A94F1C857138 = 'DD6B0870-BCEA-1520-993D-9F1337E39D4D')
 OR (ma.Status_8895EC8D_2CBF_0D9D_E8EC_524DEFA00014 = '11FC3CEF-15E5-BCA4-DEE0-9C1155EC8D83' OR ma.Status_8895EC8D_2CBF_0D9D_E8EC_524DEFA00014 = 'D544258F-24DA-1CF3-C230-B057AAA66BED')
 GROUP BY u.DisplayName,u.BaseManagedEntityId
 Order by u.DisplayName