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 の間に 1 対多の関係があると仮定しています。各 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'
    

ここでの 2 つの重要な変更は、左結合と 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 に答える