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
我已经使用 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