Sql server 2008 在联接中从一个表中提取所有行,即使在另一个表中找不到任何行

Sql server 2008 在联接中从一个表中提取所有行,即使在另一个表中找不到任何行,sql-server-2008,Sql Server 2008,我有一个几乎有7000行和一个表的视图,在一个左连接中,我认为我仍然可以从视图中提取所有内容,并在适用时将null插入到UNITCOST字段中。但是,它只提取匹配的行。下面是代码 Select vto.*, vc.UNITCOST From myView vto LEFT JOIN VeryCost vc ON vto.VI_ID = vc.VI_ID Where (vc.VC_START_DATE BETWEEN '9/4/2016' AND '10/1/2016'

我有一个几乎有7000行和一个表的视图,在一个左连接中,我认为我仍然可以从视图中提取所有内容,并在适用时将null插入到UNITCOST字段中。但是,它只提取匹配的行。下面是代码

Select vto.*, vc.UNITCOST
From myView vto
LEFT JOIN VeryCost vc
ON vto.VI_ID = vc.VI_ID
Where (vc.VC_START_DATE BETWEEN '9/4/2016' AND '10/1/2016'
             OR vc.VC_END_DATE BETWEEN '9/4/2016' AND '10/1/2016')

因此,我要做的是从视图中选择所有行,并从VeryCost表中选择UNITCOST值,其中VI字段与有效日期匹配。当VI字段匹配但日期无效时,我希望这些行的单位成本为空。

请参阅注释以了解原因

SELECT vto.*, vc.UNITCOST
FROM  myView vto
LEFT JOIN VeryCost vc
  ON vto.VI_ID = vc.VI_ID
 AND (vc.VC_START_DATE BETWEEN '9/4/2016' AND '10/1/2016'
   OR vc.VC_END_DATE BETWEEN '9/4/2016' AND '10/1/2016')
where子句否定了左连接


连接首先发生,因此连接生成的空记录存在。然后应用限制,因为VC在上,只包括那些匹配的REOCRD。。。将出现空值。由于VC.Start\u date或VC.End\u date不考虑空值,因此将排除空记录,因此where子句将否定左连接。

有关推理,请参阅注释

SELECT vto.*, vc.UNITCOST
FROM  myView vto
LEFT JOIN VeryCost vc
  ON vto.VI_ID = vc.VI_ID
 AND (vc.VC_START_DATE BETWEEN '9/4/2016' AND '10/1/2016'
   OR vc.VC_END_DATE BETWEEN '9/4/2016' AND '10/1/2016')
where子句否定了左连接


连接首先发生,因此连接生成的空记录存在。然后应用限制,因为VC在上,只包括那些匹配的REOCRD。。。将出现空值。由于VC.Start\u date或VC.End\u date不考虑空值,因此将排除空记录,因此where子句将否定左连接。

您的
where
子句说明了限制数据的原因。要说明来自
vto
的不匹配项,请使用以下方法:

Select vto.*, vc.UNITCOST
From myView vto
LEFT JOIN VeryCost vc
ON vto.VI_ID = vc.VI_ID
Where
    (vc.VI_ID is null)
    or 
    (vc.VC_START_DATE BETWEEN '9/4/2016' AND '10/1/2016' OR vc.VC_END_DATE BETWEEN '9/4/2016' AND '10/1/2016')

编辑,或者您可以将日期匹配包括在
加入
标准中,如另一个答案所述。无论哪种方式,都不要做任何强制排除不匹配项的事情。

您的
WHERE
子句将说明限制数据的原因。要说明来自
vto
的不匹配项,请使用以下方法:

Select vto.*, vc.UNITCOST
From myView vto
LEFT JOIN VeryCost vc
ON vto.VI_ID = vc.VI_ID
Where
    (vc.VI_ID is null)
    or 
    (vc.VC_START_DATE BETWEEN '9/4/2016' AND '10/1/2016' OR vc.VC_END_DATE BETWEEN '9/4/2016' AND '10/1/2016')

编辑,或者您可以将日期匹配包括在
加入
标准中,如另一个答案所述。无论哪种方式,都不要强制排除非匹配项。

where子句否定左连接。只需将单词
WHERE
更改为
;删除where子句并将限制移动到联接,这将导致在联接之前应用限制,从而允许保留所有外部联接记录。而不是被排除,因为VC是一个空值,并且求值会消除由左连接生成的空值。where子句否定左连接。只需将单词
WHERE
更改为
;删除where子句并将限制移动到联接,这将导致在联接之前应用限制,从而允许保留所有外部联接记录。不是因为VC是空值而被排除,而是因为求值消除了由左join生成的空值。您不想检查VC.VI_ID吗?(外键)而不是日期?填写VC.VI_ID时,日期为空可能是合法的;但这会包括他们。你不想检查一下VC.VI_ID吗?(外键)而不是日期?填写VC.VI_ID时,日期为空可能是合法的;但这也包括他们。非常感谢你的回答!非常感谢您的回答!