按 ID 匹配记录并在 SQL 中显示不匹配的列

Matching records by ID and displaying non-matching columns in TSQL

在 SQL 服务器中,我有两个 tables,注册员记录和教师记录,它们是相同的。查询的第一部分与学生 ID 匹配,并显示是否在动态列中找到匹配项(我已经完成了那部分)。

一个额外的动态列应该列出所有不匹配的列 - 我想知道是否有一种方法可以做到这一点而无需制作巨大的 Case 表达式,因为那会有很多可能性,这就是我到目前为止:

SET ANSI_NULLS OFF

SELECT TR.*,
        CASE WHEN RR.StudentID IS NULL THEN 'NO MATCH'
             WHEN RR.StudentID IS NOT NULL AND RR.FirstName = TR.FirstName
                                           AND RR.LastName = TR.LastName
                                           AND RR.Floor = TR.Floor
                                           AND RR.FirstQuarterGrade = TR.FirstQuarterGrade
                                           AND RR.SecondQuarterGrade = TR.SecondQuarterGrade
                                           AND RR.ThirdQuarterGrade = TR.ThirdQuarterGrade
                                           AND RR.FinalGrade = TR.FinalGrade THEN 'MATCH'
            ELSE 'MATCH WITH ISSUE' END AS MatchResult
        --TO DO: Add a ISSUE column; lists columns with mismatch
FROM TeacherRecords TR
      LEFT JOIN RegistrarRecords RR ON RR.StudentID = TR.StudentID

如果 table 需要脚本,这里是 table:

CREATE TABLE [dbo].[RegistrarRecords](
    [StudentID] [varchar](10) NOT NULL,
    [FirstName] [varchar](50) NULL,
    [LastName] [varchar](50) NULL,
    [Floor] [int] NULL,
    [Room] [varchar](10) NULL,
    [FirstQuarterGrade] [int] NULL,
    [SecondQuarterGrade] [int] NULL,
    [ThirdQuarterGrade] [int] NULL,
    [FinalGrade] [int] NULL
) ON [PRIMARY]

您可以将此查询分成两部分

  • 首先找出所有问题
  • 然后检查做最后的有没有问题select

这是执行此操作的示例代码。 Issue_List 字段包含所有有问题的列的逗号分隔列表(例如,'Floor, FirstQuarterGrade')。如果此字段为空,则表示没有问题。

WITH TR_Match_Info AS
    (SELECT TR.*, 
        RR.StudentID AS RR_StudentID,
        '' + CASE WHEN RR.FirstName = TR.FirstName THEN '' ELSE 'FirstName, ' END
           + CASE WHEN RR.LastName = TR.LastName THEN '' ELSE 'LastName, ' END
           + CASE WHEN RR.Floor = TR.Floor THEN '' ELSE 'Floor, ' END
           + CASE WHEN RR.FirstQuarterGrade = TR.FirstQuarterGrade THEN '' ELSE 'FirstQuarterGrade, ' END
           + CASE WHEN RR.SecondQuarterGrade = TR.SecondQuarterGrade THEN '' ELSE 'SecondQuarterGrade, ' END
           + CASE WHEN RR.ThirdQuarterGrade = TR.ThirdQuarterGrade THEN '' ELSE 'ThirdQuarterGrade, ' END
           + CASE WHEN RR.FinalGrade = TR.FinalGrade THEN '' ELSE 'FinalGrade, ' END
           AS Issue_List
    FROM TeacherRecords TR
          LEFT JOIN RegistrarRecords RR ON RR.StudentID = TR.StudentID
    )
SELECT  [StudentID],
        [FirstName],
        [LastName],
        [Floor],
        [Room],
        [FirstQuarterGrade],
        [SecondQuarterGrade],
        [ThirdQuarterGrade],
        [FinalGrade],
        CASE WHEN RR_StudentID IS NULL THEN 'NO MATCH'
             WHEN Issue_List = '' THEN 'MATCH'
             ELSE 'MATCH WITH ISSUE' END 
             AS MatchResult,
        CASE WHEN RR_StudentID IS NULL THEN ''
             WHEN LEN(Issue_List) > 0 THEN LEFT(Issue_List, LEN(Issue_List) - 1)
             ELSE Issue_List
             END AS Match_Issues
FROM TR_Match_Info;

请注意,上述问题检查基于您的代码。您应该查看 NULL 的处理方式 - 如果两个值都为 NULL,则将其标记为一个问题(例如,当检查 NULL = NULL 结果是否为 NULL 时,它会转到这些 CASE 表达式的 ELSE 组件)。