选择中的案例陈述

时间:2012-08-31 20:34:38

标签: sql sql-server duplicates case

我正在尝试运行以下查询,但是当我只想要拉出一条记录时,我的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'

3 个答案:

答案 0 :(得分:4)

我假设你在SyStudent和CmEvent之间有一对多的关系。鉴于每个SyStudent可能在列表内外都有相应的CmEvent(714,716,732,734),这将解释为什么您的查询可能为每个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记录。其次,案例陈述发生了变化。现在我们使用CmEvent.SyStudentID的存在来确定SyStudent在给定列表中是否具有CmEvent.CmtemplateID。如果左连接没有产生匹配,那么就知道它们没有匹配。

答案 1 :(得分:1)

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

另外,考虑使用1而不是'yes'而0而不是'no'

另外,请考虑使用表别名。

答案 2 :(得分: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在性能方面优于DISTINCTreference here