为什么我的内部联接不起作用

时间:2015-12-18 10:25:37

标签: sql-server tsql

这是一个令人尴尬的问题!但是我已经有一段时间没用过tsql了。

我有3张桌子:

  • 工作
  • JobWorkUnit

Gallery的主键链接到Job中的相应外键。 JobWorkUnit的主键与Job

中的相应外键相关联

我希望返回Job上的所有记录,无论他们是否有'链接'在其他2个表中。

我原以为使用LEFT OUTER JOIN是这样做的方法,但我根本没有回复记录。

有人可以查看我的代码吗?

SELECT 
    *
FROM 
    Job J
LEFT OUTER JOIN 
    Gallery G ON G.JobRef = J.JobRef
LEFT OUTER JOIN 
    JobWorkUnit JWU ON J.JobRef = JWU.JobRef
WHERE 
    J.Active = 1 
    AND G.Active = 1 
    AND JWU.Active = 1 
    AND J.CompanyRef = @CompanyRef

WorkUnitGallery

中没有记录

如果我删除:

AND G.Active = 1 
AND JWU.Active = 1 

我得到2条记录,所以我的Where子句覆盖了我的连接类型。这是公平的说法吗?

3 个答案:

答案 0 :(得分:5)

您应该将过滤移动到连接条件,其他方式只是过滤掉带有空值的行:

SELECT  *
FROM    Job J
        LEFT OUTER JOIN Gallery G ON G.JobRef = J.JobRef
                                     AND G.Active = 1
        LEFT OUTER JOIN JobWorkUnit JWU ON J.JobRef = JWU.JobRef
                                           AND JWU.Active = 1
WHERE   J.Active = 1
        AND J.CompanyRef = @CompanyRef

答案 1 :(得分:2)

仅当job表为空

时,此查询才会返回零结果

更新:显示where

SELECT *
FROM Job J
    left join Gallery G ON J.JobRef = G.JobRef 
        and G.Active = 1
    left join JobWorkUnit JWU on J.JobRef = JWU.JobRef
        and JWU.Active = 1
where J.Active = 1 
    and J.CompanyRef = @CompanyRef

答案 2 :(得分:2)

这只是风格/清晰度的问题,但我不想在连接条件下过滤数据。我这样重写你的查询:

SELECT 
*
FROM 
    Job J
Left OUTER JOIN Gallery G 
ON
     G.JobRef = J.JobRef
LEFT OUTER JOIN JobWorkUnit JWU
ON
     J.JobRef = JWU.JobRef
WHERE 
    J.Active = 1 
AND
    (G.Active = 1 OR G.Active IS NULL)
AND
    (JWU.Active = 1 OR JWU.Active IS NULL)
AND
    J.CompanyRef = @CompanyRef

就个人而言,我认为最明确地表达了查询的意图。

修改 刚刚意识到没有人真正明确解释为什么

执行外连接时,如果没有连接,则外连接表的字段为空。如果您在WHERE子句中使用这些字段,它们将失败所有过滤条件(当然除了IS NULL),就像空值一样。