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

T-SQL : Avoid Subquery in favor of aggregation

我已经使用 T-SQL 很长时间了,但我无法比我更好地进行聚合,这个例子将强调这一点。我敢肯定可能存在与此相关的问题,但是,我不知道如何提问,我也不知道如何搜索它。

我有一个视图汇总了每个团队成员的一些 activity 日志记录 Sample ActivityDetail ...

我需要为此做的一件事是获取给定时间段内所有团队成员的聚合(Activity 按成员计数)。我发现使用本网站其他地方的连接技巧很容易在每个 Member/Activity 的专用行中获得 Per-Activity 总计

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

这很好地得到了我想要的输出(包括零表示没有 activity)。 Desired Output

但是 (a) 这是低效的 - 它已经表现不佳,并且 (b) 这只是尖叫聚合,但我显然太笨了,无法想出正确的方法来构建它来获得我正在寻找的东西为了。有帮助吗?

您可以使用 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