T-SQL:避免使用子查询来支持聚合

时间:2018-02-26 16:42:12

标签: tsql aggregation

我已经使用T-SQL很长时间了,不能比我更好地进行聚合,这个例子将突出显示。我确定可能存在一些问题,但是,如果不知道如何提出问题,我也不知道如何更好地搜索它。

我有一个视图,聚合每个团队成员的一些活动记录 Sample ActivityDetail ...

我需要做的一件事是在给定时间段内为所有团队成员获得聚合(按成员计算活动数)。我发现使用在本网站其他地方找到的串联黑客,每个成员/活动专用行中的Per-Activity Totals很容易

SELECT DISTINCT
      a.Member
    , a.Activity
    , COUNT(CONCAT(a.Member,a.Activity)) AS ActivityCount

FROM v_Activity a 
WHERE    a.Activity_Date > DATEADD(DAY,-7,GETDATE()) 
GROUP BY a.Member,a.Activity
ORDER BY a.Member

Sample ActivityTotals 但我们在这里真正需要的是更加统一的代表。现在,我知道我可以使用子查询为每个ActivityType执行COUNT(*),如此

SELECT DISTINCT
      a.Member
    , (SELECT COUNT(*) FROM v_UpdateActivity WHERE Member = a.Member AND Activity = 'Create' AND Activity_Date > DATEADD(DAY,-7,GETDATE())) As Created
    , (SELECT COUNT(*) FROM v_UpdateActivity WHERE Member = a.Member AND Activity = 'Update' AND Activity_Date > DATEADD(DAY,-7,GETDATE())) As Updated
    , (SELECT COUNT(*) FROM v_UpdateActivity WHERE Member = a.Member AND Activity = 'Document' AND Activity_Date > DATEADD(DAY,-7,GETDATE())) As Documented
    , (SELECT COUNT(*) FROM v_UpdateActivity WHERE Member = a.Member AND Activity = 'Deactivate' AND Activity_Date > DATEADD(DAY,-7,GETDATE())) As Deactivated
    , (SELECT COUNT(*) FROM v_UpdateActivity WHERE Member = a.Member AND Activity = 'Reactivate' AND Activity_Date > DATEADD(DAY,-7,GETDATE())) As Reactivated

FROM v_cw_ConfigUpdateActivity a 
WHERE    a.Activity_Date > DATEADD(DAY,-7,GETDATE()) 
ORDER BY a.Member

这对于获得我想要的输出(包括没有活动的零)来说是一个不错的工作。 Desired Output

但是(a)这是效率低下的 - 它已经表现不佳而且(b)这只是尖叫聚集但我显然太厚了,无法想出正确的方法来构建这个以获得我所做的事情。我正在寻找。有什么帮助吗?

1 个答案:

答案 0 :(得分:2)

您可以使用CASE语句和GROUP BY代替子查询。或者你可以用PIVOT来做到这一点。

SELECT 
      a.Member
      SUM(CASE WHEM Activity = 'Create' THEN 1 ELSE 0 END) as Created,
      SUM(CASE WHEM Activity = 'Updated' THEN 1 ELSE 0 END) as Updated,
      SUM(CASE WHEM Activity = 'Documented' THEN 1 ELSE 0 END) as Documented,
      SUM(CASE WHEM Activity = 'Deactivated' THEN 1 ELSE 0 END) as Deactivated,
      SUM(CASE WHEM Activity = 'Reactivated' THEN 1 ELSE 0 END) as Reactivated    
FROM v_cw_ConfigUpdateActivity a 
WHERE    a.Activity_Date > DATEADD(DAY,-7,GETDATE()) 
GROUP BY a.Member
ORDER BY a.Member;

我的tsql技能可能会在这里显示它们的生锈,但这是对PIVOT版本的尝试:

SELECT
    Member,
    Created,
    Updated,
    Documented,
    Deactivated,
    Reactivated
FROM (SELECT Member, Activity FROM v_cw_ConfigUpdateActivity) as SourceTable
PIVOT (COUNT(Activity) FOR Member IN (Created, Updated, Documented, Deactivated, Reactivated) as PivotTable