手头的问题是无法在select语句中使用具有以下所需输出的子查询:
ActivityName参加进行中取消已注册
- ProdA 8 3 1 2
- ProdB 16 5 3 4
以下是我当前代码的示例。有没有办法不使用子查询?
select
(select act.ActivityName
from [dbo].[dimActivity] act
WHERE act.Code in ('SJM-GTD-HMM-A01')
) ActivityName,
(Select count( emp.ID)
FROM [dbo].[factAttempt] fact
INNER JOIN [dbo].[dimActivity] act ON act.ID = fact.ActivityID
INNER JOIN [dbo].[dimUser] emp ON emp.ID = fact.UserID
INNER JOIN [dbo].[dimDate] dt ON fact.EndDtID = dt.DateID
INNER JOIN [dbo].[dimCompletionStatus] comp ON fact.CompletionStatusID = comp.ID
INNER JOIN [dbo].[dimAttendanceStatus] att ON fact.AttendanceStatusID = att.ID
WHERE (act.Code in ('SJM-GTD-HMM-A01','SJM-GTD-HMM-MAN01','SJM-GTD-HMM-PRT01','SJM-GTD-HMM-LAS01'))
and att.name like ('%Attend%')
) Attended,
(Select count( emp.ID)
FROM [dbo].[factAttempt] fact
INNER JOIN [dbo].[dimActivity] act ON act.ID = fact.ActivityID
INNER JOIN [dbo].[dimUser] emp ON emp.ID = fact.UserID
INNER JOIN [dbo].[dimDate] dt ON fact.EndDtID = dt.DateID
INNER JOIN [dbo].[dimCompletionStatus] comp ON fact.CompletionStatusID = comp.ID
INNER JOIN [dbo].[dimAttendanceStatus] att ON fact.AttendanceStatusID = att.ID
WHERE (act.Code in ('SJM-GTD-HMM-A01','SJM-GTD-HMM-MAN01','SJM-GTD-HMM-PRT01','SJM-GTD-HMM-LAS01'))
and att.name like ('%Progress%')
) Inprogess,
(Select count( emp.ID)
FROM [dbo].[factAttempt] fact
INNER JOIN [dbo].[dimActivity] act ON act.ID = fact.ActivityID
INNER JOIN [dbo].[dimUser] emp ON emp.ID = fact.UserID
INNER JOIN [dbo].[dimDate] dt ON fact.EndDtID = dt.DateID
INNER JOIN [dbo].[dimCompletionStatus] comp ON fact.CompletionStatusID = comp.ID
INNER JOIN [dbo].[dimAttendanceStatus] att ON fact.AttendanceStatusID = att.ID
WHERE (act.Code in ('SJM-GTD-HMM-A01','SJM-GTD-HMM-MAN01','SJM-GTD-HMM-PRT01','SJM-GTD-HMM-LAS01'))
and att.name like ('%Cancel%')
) Cancelled,
(Select count( emp.ID)
FROM [dbo].[factAttempt] fact
INNER JOIN [dbo].[dimActivity] act ON act.ID = fact.ActivityID
INNER JOIN [dbo].[dimUser] emp ON emp.ID = fact.UserID
INNER JOIN [dbo].[dimDate] dt ON fact.EndDtID = dt.DateID
INNER JOIN [dbo].[dimCompletionStatus] comp ON fact.CompletionStatusID = comp.ID
INNER JOIN [dbo].[dimAttendanceStatus] att ON fact.AttendanceStatusID = att.ID
WHERE (act.Code in ('SJM-GTD-HMM-A01','SJM-GTD-HMM-MAN01','SJM-GTD-HMM-PRT01','SJM-GTD-HMM-LAS01'))
and att.name like ('%NA%')
) Registered
答案 0 :(得分:2)
主要选择'ActivityName'应该是主查询,每个子查询都嵌套在里面,格式为:
SELECT act.ActivityName, {otherSubqueriesGoHere}
FROM [dbo].[dimActivity] act
WHERE act.Code in ('SJM-GTD-HMM-A01')
然后,在子查询中,您可以引用主结果集中的值,以便将子查询结果过滤为仅当前行的活动。
以下是修改后的查询示例。您需要更改每个子查询中的and act.ID = actMain.ID
部分,以使用dimActivity
表的主键而不是ID
。我刚刚使用ID
,因为我不知道你的表结构是什么。
SELECT
actMain.ActivityName,
( Select count( emp.ID)
FROM [dbo].[factAttempt] fact
INNER JOIN [dbo].[dimActivity] act ON act.ID = fact.ActivityID
INNER JOIN [dbo].[dimUser] emp ON emp.ID = fact.UserID
INNER JOIN [dbo].[dimDate] dt ON fact.EndDtID = dt.DateID
INNER JOIN [dbo].[dimCompletionStatus] comp ON fact.CompletionStatusID = comp.ID
INNER JOIN [dbo].[dimAttendanceStatus] att ON fact.AttendanceStatusID = att.ID
WHERE (act.Code in ('SJM-GTD-HMM-A01','SJM-GTD-HMM-MAN01','SJM-GTD-HMM-PRT01','SJM-GTD-HMM-LAS01'))
and att.name like ('%Attend%')
and act.ID = actMain.ID
) Attended,
( Select count( emp.ID)
FROM [dbo].[factAttempt] fact
INNER JOIN [dbo].[dimActivity] act ON act.ID = fact.ActivityID
INNER JOIN [dbo].[dimUser] emp ON emp.ID = fact.UserID
INNER JOIN [dbo].[dimDate] dt ON fact.EndDtID = dt.DateID
INNER JOIN [dbo].[dimCompletionStatus] comp ON fact.CompletionStatusID = comp.ID
INNER JOIN [dbo].[dimAttendanceStatus] att ON fact.AttendanceStatusID = att.ID
WHERE (act.Code in ('SJM-GTD-HMM-A01','SJM-GTD-HMM-MAN01','SJM-GTD-HMM-PRT01','SJM-GTD-HMM-LAS01'))
and att.name like ('%Progress%')
and act.ID = actMain.ID
) Inprogess,
( Select count( emp.ID)
FROM [dbo].[factAttempt] fact
INNER JOIN [dbo].[dimActivity] act ON act.ID = fact.ActivityID
INNER JOIN [dbo].[dimUser] emp ON emp.ID = fact.UserID
INNER JOIN [dbo].[dimDate] dt ON fact.EndDtID = dt.DateID
INNER JOIN [dbo].[dimCompletionStatus] comp ON fact.CompletionStatusID = comp.ID
INNER JOIN [dbo].[dimAttendanceStatus] att ON fact.AttendanceStatusID = att.ID
WHERE (act.Code in ('SJM-GTD-HMM-A01','SJM-GTD-HMM-MAN01','SJM-GTD-HMM-PRT01','SJM-GTD-HMM-LAS01'))
and att.name like ('%Cancel%')
and act.ID = actMain.ID
) Cancelled,
( Select count( emp.ID)
FROM [dbo].[factAttempt] fact
INNER JOIN [dbo].[dimActivity] act ON act.ID = fact.ActivityID
INNER JOIN [dbo].[dimUser] emp ON emp.ID = fact.UserID
INNER JOIN [dbo].[dimDate] dt ON fact.EndDtID = dt.DateID
INNER JOIN [dbo].[dimCompletionStatus] comp ON fact.CompletionStatusID = comp.ID
INNER JOIN [dbo].[dimAttendanceStatus] att ON fact.AttendanceStatusID = att.ID
WHERE (act.Code in ('SJM-GTD-HMM-A01','SJM-GTD-HMM-MAN01','SJM-GTD-HMM-PRT01','SJM-GTD-HMM-LAS01'))
and att.name like ('%NA%')
and act.ID = actMain.ID
) Registered
FROM [dbo].[dimActivity] actMain
WHERE actMain.Code in ('SJM-GTD-HMM-A01')
修改强>
我只是注意到你的每个子查询基本上都是重复的,只有att.name
更改的比较,所以你也可以使用这样的查询,其中包括group by和sum来计算每个查询的出现次数{ {1}}值。
att.name
注意:此查询不包括对所有4个桶(出席,进行,取消,已注册)具有0计数的SELECT act.ActivityName
, SUM(case when att.name like ('%Attend%') then 1 else 0 end) as Attended
, SUM(case when att.name like ('%Progress%') then 1 else 0 end) as Inprogess
, SUM(case when att.name like ('%Cancel%') then 1 else 0 end) as Cancelled
, SUM(case when att.name like ('%NA%') then 1 else 0 end) as Registered
FROM [dbo].[factAttempt] fact
INNER JOIN [dbo].[dimActivity] act ON act.ID = fact.ActivityID
INNER JOIN [dbo].[dimUser] emp ON emp.ID = fact.UserID
INNER JOIN [dbo].[dimDate] dt ON fact.EndDtID = dt.DateID
INNER JOIN [dbo].[dimCompletionStatus] comp ON fact.CompletionStatusID = comp.ID
INNER JOIN [dbo].[dimAttendanceStatus] att ON fact.AttendanceStatusID = att.ID
WHERE (act.Code in ('SJM-GTD-HMM-A01','SJM-GTD-HMM-MAN01','SJM-GTD-HMM-PRT01','SJM-GTD-HMM-LAS01'))
GROUP BY act.ActivityName
。如果您需要包含全0的记录,那么您可以将联接更改为ActivityName
,如下所示:
LEFT JOIN