Sql 无法在语句中的select中使用子查询

Sql 无法在语句中的select中使用子查询,sql,sql-server,Sql,Sql Server,当前的问题是无法在select语句中使用具有以下所需输出的子查询: 已取消注册的过程中参加的活动名称 - ProdA 8 3 1 2 - ProdB 16 5 3 4 这是我当前代码的一个示例。有没有办法不使用子查询 select (select act.ActivityName from [dbo].[dimActivity] act W

当前的问题是无法在select语句中使用具有以下所需输出的子查询:

已取消注册的过程中参加的活动名称

 - 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

“ActivityName”的主选择应包含在主查询中,每个子查询嵌套在其中,格式如下:

SELECT act.ActivityName, {otherSubqueriesGoHere} 
FROM [dbo].[dimActivity] act 
WHERE act.Code in ('SJM-GTD-HMM-A01')
然后,在子查询中,可以引用主结果集中的值,以便仅将子查询结果筛选到当前行的活动

下面是一个修改查询的示例。您需要更改每个子查询中的
和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来计算每个
att.name
值的出现次数

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 
注意:此查询不包括对所有4个存储桶(已出席、正在进行、已取消、已注册)计数为0的活动名。如果需要包含所有0的记录,则可以将联接更改为
LEFT JOIN
s,如下所示:

FROM [dbo].[dimActivity] act
    LEFT JOIN [dbo].[factAttempt] fact ON act.ID = fact.ActivityID
    LEFT JOIN [dbo].[dimUser] emp ON emp.ID = fact.UserID
    LEFT JOIN [dbo].[dimDate] dt ON fact.EndDtID = dt.DateID
    LEFT JOIN [dbo].[dimCompletionStatus] comp ON fact.CompletionStatusID = comp.ID
    LEFT JOIN [dbo].[dimAttendanceStatus] att ON fact.AttendanceStatusID = att.ID

看起来很复杂!关于子查询,您想知道什么?有没有一种方法可以在没有子查询的情况下计算行总数?您所需的“产品名称”、“类型计数”和“用户计数”列的输出与您发布的“活动名称”、“参与”、“正在进行”、“取消”和“已注册”列的查询不匹配。由于预期结果与查询不一致,因此很难确切地说出您想要的是什么,但问题很可能是您对“ActivityName”的主选择应该是主查询,每个子查询都嵌套在格式为“select act.ActivityName,{otherSubqueriesHere}FROM[dbo].[dimActivity]act WHERE act.Code in”的主查询中('SJM-GTD-HMM-A01')。dimActivity表上的主键是什么?您需要在子查询中使用它来获取每个Activity@BateTech的小计-软件供应商不允许在其应用程序中使用子查询,因此出现了问题。在Visual Studio 2008中,查询执行得非常完美,输出是正确的。