左连接没有加入单个记录

时间:2016-04-22 05:49:28

标签: sql sql-server database join

我有以下查询:

Insert into cet_database.dbo.termData
    (
        termID,
        studentID,
        course,
        [current],
        program,
        StbyCurrentClassID,
        class,
        classCode,
        cancelled
    )
    Select
        fm_stg.classByStudent_termData_assessmentData.termID,
        fm_stg.classByStudent_termData_assessmentData.studentID,
        fm_stg.classByStudent_termData_assessmentData.class_code,
        case when fm_stg.classByStudent_termData_assessmentData.[current] = 'Yes' then 1 else 0 end,
        fm_stg.classByStudent_termData_assessmentData.program,
        fm_stg.classByStudent_termData_assessmentData.classByStudentID,
        fm_stg.classByStudent_termData_assessmentData.class,
        fm_stg.classByStudent_termData_assessmentData.classID,
        case when fm_stg.classByStudent_termData_assessmentData.cancelled_flag = 1 then 1 else 0 end
From fm_stg.classByStudent_termData_assessmentData left outer join termData
    On fm_stg.classByStudent_termData_assessmentData.class_code = termData.course
    and fm_stg.classByStudent_termData_assessmentData.termID = termData.termID
    and fm_stg.classByStudent_termData_assessmentData.studentID = fm_stg.classByStudent_termData_assessmentData.studentID
Where termData.StbyCurrentClassID is null

我使用查询将数据从另一个数据库(fm_stg.classByStudent_termData_assessmentData)导入到临时表中,然后再将其导入到我的数据库表中。此特定查询是较大存储过程的一部分,该过程将数据导入到与termData相关的多个表中。

当我运行sproc时,我将记录插入fm_stg.classByStudent_termData_assessmentData但不插入termData。我遇到这个问题时只插入一条记录,但它适用于我以前做过的10,000条记录。我使用左连接来建立我的数据库表中已存在的内容以及什么不存在,然后从登台表中获取相关记录。但是,有了这条记录:

316a, 39520, DEC 10, Yes, DEC10, 105713, DEC 10 (18), 6078, NULL, 2

选择没有返回 - 这是为什么?该记录肯定不存在于我的termData表中,并且记录从登台表插入到我的所有其他表中。 sproc正在运行事务中的所有插入,以便准确地避免在某些表中而不是其他表中插入记录的情况,但它似乎没有工作。

1 个答案:

答案 0 :(得分:1)

您说该查询适用于之前的10,000条记录,但不适用于当前的记录。查询中唯一看起来很奇怪的是ON子句中的第三行,您可以将字段(studentID)与自身进行比较。

On fm_stg.classByStudent_termData_assessmentData.class_code = termData.course
and fm_stg.classByStudent_termData_assessmentData.termID = termData.termID
and fm_stg.classByStudent_termData_assessmentData.studentID = fm_stg.classByStudent_termData_assessmentData.studentID

我只是在这里猜测,但由于 ON子句中,您是否也要比较学生ID?所以你可能很幸运,查询到目前为止工作,现在你偶然发现了学生证。我想ON子句看起来像这样:

On fm_stg.classByStudent_termData_assessmentData.class_code = termData.course
and fm_stg.classByStudent_termData_assessmentData.termID = termData.termID
and fm_stg.classByStudent_termData_assessmentData.studentID = termData.studentID

顺便说一下,使用表别名可以使查询更具可读性。在以下查询中,我对ad使用fm_stg.classByStudent_termData_assessmentDatatd使用termData

Insert into cet_database.dbo.termData
(
  termID,
  studentID,
  course,
  [current],
  program,
  StbyCurrentClassID,
  class,
  classCode,
  cancelled
)
Select
  ad.termID,
  ad.studentID,
  ad.class_code,
  case when ad.[current] = 'Yes' then 1 else 0 end,
  ad.program,
  ad.classByStudentID,
  ad.class,
  ad.classID,
  case when ad.cancelled_flag = 1 then 1 else 0 end
From fm_stg.classByStudent_termData_assessmentData ad
Left Outer Join termData td On  ad.class_code = td.course
                            And ad.termID     = td.termID
                            And ad.studentID  = td.studentID
Where td.StbyCurrentClassID is null;

此外,在检查存在时,为什么要使用反连接技巧?你有直截了当NOT EXISTS的问题吗?仅在真正需要时使用技巧。查询读取更好,如下所示:

Insert into cet_database.dbo.termData
(
  termID,
  studentID,
  course,
  [current],
  program,
  StbyCurrentClassID,
  class,
  classCode,
  cancelled
)
  Select
    termID,
    studentID,
    class_code,
    case when [current] = 'Yes' then 1 else 0 end,
    program,
    classByStudentID,
    class,
    classID,
    case when cancelled_flag = 1 then 1 else 0 end
  From fm_stg.classByStudent_termData_assessmentData ad
  Where Not Exists
  (
     Select *
     From termData td 
     Where ad.class_code = td.course
       And ad.termID     = td.termID
       And ad.studentID  = td.studentID
);

使用另一个DBMS,您甚至可以使用NOT IN(即Where (class_code, termId, studenId) Not In (Select ...)),这是不相关的,因此甚至不会发生这样的拼写错误,但SQL Server没有使用元组。不幸的是IN条款。