0

我正在尝试运行以下查询,但是Case当我只希望提取一条记录时,即使他们同时具备这两个条件,我的语句中同时存在两个要求的人也会遇到问题。

SELECT DISTINCT
    SyCampus.Descrip AS 'Campus',
    dbo.rpt_adAttendanceDetail_vw.instructorname AS 'Instructor Name',
    dbo.rpt_adAttendanceDetail_vw.classcode AS 'Class Code',
    dbo.rpt_adAttendanceDetail_vw.section AS 'Section',
    dbo.rpt_adAttendanceDetail_vw.classdescrip AS 'Class',
    RTRIM(SyStudent.FirstName) + ' ' + ' '  + RTRIM(SyStudent.LastName) AS 'Student Name',
    dbo.rpt_adAttendanceDetail_vw.stunum AS 'Student Number',
    CASE WHEN  CmEvent.CmtemplateID IN (714, 716, 732,734)THEN 'YES' ELSE 'NO' END  AS 'Instructor Contact'


FROM 
    dbo.rpt_adAttendanceDetail_vw
 JOIN
    SyStudent
        ON SyStudent.SyStudentID = dbo.rpt_adAttendanceDetail_vw.SyStudentID
 JOIN
    SyCampus
        ON Sycampus.SycampusID = SyStudent.SyCampusID
 JOIN
    CmEvent
        ON CmEvent.SyStudentID = SyStudent.SyStudentID

WHERE   dbo.rpt_adAttendanceDetail_vw.AttMin = '0'
    AND dbo.rpt_adAttendanceDetail_vw.date = DATEADD(d, DATEDIFF(d, 0, GETDATE()), 0) -1
    AND SyStudent.SySchoolStatusID IN (13, 129, 130, 132, 72, 59, 122, 14)
    AND dbo.rpt_adAttendanceDetail_vw.attendtype <> 'E'
    AND CmEvent.CmEventStatusid = '2'
4

3 回答 3

4

我假设您在 SyStudent 和 CmEvent 之间存在一对多的关系。鉴于每个 SyStudent 可能在列表内外(714、716、732,734)都有相应的 CmEvent,这将解释为什么您的查询可能会为每个 SyStudent 返回多个记录。如果您想知道 SyStudent 在给定列表中是否有 CmEvent.CmtemplateID,您可以在联接中处理它。

考虑对您的查询进行以下更改:


SELECT DISTINCT
    SyCampus.Descrip AS 'Campus',
    dbo.rpt_adAttendanceDetail_vw.instructorname AS 'Instructor Name',
    dbo.rpt_adAttendanceDetail_vw.classcode AS 'Class Code',
    dbo.rpt_adAttendanceDetail_vw.section AS 'Section',
    dbo.rpt_adAttendanceDetail_vw.classdescrip AS 'Class',
    RTRIM(SyStudent.FirstName) + ' ' + ' '  + RTRIM(SyStudent.LastName) AS 'Student Name',
    dbo.rpt_adAttendanceDetail_vw.stunum AS 'Student Number',
    CASE WHEN CmEvent.SyStudentID THEN 'YES' ELSE 'NO' END  AS 'Instructor Contact'
    FROM 
    dbo.rpt_adAttendanceDetail_vw 
JOIN
    SyStudent
        ON SyStudent.SyStudentID = dbo.rpt_adAttendanceDetail_vw.SyStudentID
 JOIN
    SyCampus
        ON Sycampus.SycampusID = SyStudent.SyCampusID
 LEFT JOIN
    CmEvent
        ON CmEvent.SyStudentID = SyStudent.SyStudentID 
        AND CmEvent.CmEventStatusid = '2'
        AND CmEvent.CmtemplateID IN (714, 716, 732,734)
WHERE   dbo.rpt_adAttendanceDetail_vw.AttMin = '0'
    AND dbo.rpt_adAttendanceDetail_vw.date = DATEADD(d, DATEDIFF(d, 0, GETDATE()), 0) -1
    AND SyStudent.SySchoolStatusID IN (13, 129, 130, 132, 72, 59, 122, 14)
    AND dbo.rpt_adAttendanceDetail_vw.attendtype <> 'E'
    

这里的两个显着变化是左连接和 case 语句。首先,我们将 CmEvent 标准移动到左连接中。通过这样做,我们将只加入 CmEvent 中符合我们标准的记录。这将忽略模板 ID 在我们列表之外的所有 CmEvent 记录。其次,改变了case语句。现在我们使用 CmEvent.SyStudentID 的存在来确定 SyStudent 在给定列表中是否有 CmEvent.CmtemplateID。如果左连接没有产生匹配,那么就知道它们没有。

于 2012-08-31T21:32:13.733 回答
1

我的猜测是你想要一个返回 max('Instructor Contact') 的外部聚合查询。

此外,考虑使用 1 代替“是”和 0 代替“否”

另外,考虑使用表别名。

于 2012-08-31T21:02:07.697 回答
1

case有效地将这些数字 714、716、732,734 中的一个替换为是或否,因此它看起来重复,但它正在按照您的要求进行操作。我认为,如果您在GROUP BY所有SELECT领域都应该有不同的结果。

看看这里的SQL FIDDLE

所以你可以这样做:

   SELECT 
        SyCampus.Descrip AS 'Campus',
        dbo.rpt_adAttendanceDetail_vw.instructorname AS 'Instructor Name',
        dbo.rpt_adAttendanceDetail_vw.classcode AS 'Class Code',
        dbo.rpt_adAttendanceDetail_vw.section AS 'Section',
        dbo.rpt_adAttendanceDetail_vw.classdescrip AS 'Class',
        RTRIM(SyStudent.FirstName) + ' ' + ' '  + RTRIM(SyStudent.LastName) AS 'Student Name',
        dbo.rpt_adAttendanceDetail_vw.stunum AS 'Student Number',
        CASE WHEN  CmEvent.CmtemplateID IN (714, 716, 732,734)THEN 'YES' ELSE 'NO' END  AS 'Instructor Contact'


    FROM 
        dbo.rpt_adAttendanceDetail_vw
     JOIN
        SyStudent
            ON SyStudent.SyStudentID = dbo.rpt_adAttendanceDetail_vw.SyStudentID
     JOIN
        SyCampus
            ON Sycampus.SycampusID = SyStudent.SyCampusID
     JOIN
        CmEvent
            ON CmEvent.SyStudentID = SyStudent.SyStudentID

    WHERE   dbo.rpt_adAttendanceDetail_vw.AttMin = '0'
        AND dbo.rpt_adAttendanceDetail_vw.date = DATEADD(d, DATEDIFF(d, 0, GETDATE()), 0) -1
        AND SyStudent.SySchoolStatusID IN (13, 129, 130, 132, 72, 59, 122, 14)
        AND dbo.rpt_adAttendanceDetail_vw.attendtype <> 'E'
        AND CmEvent.CmEventStatusid = '2'
   GROUP BY
        SyCampus.Descrip,
        dbo.rpt_adAttendanceDetail_vw.instructorname,
        dbo.rpt_adAttendanceDetail_vw.classcode,
        dbo.rpt_adAttendanceDetail_vw.section,
        dbo.rpt_adAttendanceDetail_vw.classdescrip,
        RTRIM(SyStudent.FirstName) + ' ' + ' '  + RTRIM(SyStudent.LastName),
        dbo.rpt_adAttendanceDetail_vw.stunum,
        CASE WHEN  CmEvent.CmtemplateID IN (714, 716, 732,734)THEN 'YES' ELSE 'NO' END  

在一个小查询中,可能没有太多收获,但我认为在性能方面GROUP BY更可取DISTINCT参考这里

于 2012-08-31T22:29:33.643 回答