Sql server 当第二个表没有值时,左外部联接不返回结果

Sql server 当第二个表没有值时,左外部联接不返回结果,sql-server,join,Sql Server,Join,我有一个SELECT语句,它有一个LEFT-OUTTER-JOIN,它将导致一个表连接到自身。我遇到的问题是,当连接右侧没有结果时,整个查询不会返回任何结果。我相信这是由于我的WHERE子句造成的,但我尝试使用COALESCE和NULL作为第二个值,但没有得到任何结果 以下是我的SQL查询: SELECT tch1.WeekEndingDate AS WeekEndingDate, tch1.TotalHoursWorked AS TotalHoursWorked,

我有一个SELECT语句,它有一个
LEFT-OUTTER-JOIN
,它将导致一个表连接到自身。我遇到的问题是,当连接右侧没有结果时,整个查询不会返回任何结果。我相信这是由于我的
WHERE
子句造成的,但我尝试使用
COALESCE
NULL
作为第二个值,但没有得到任何结果

以下是我的SQL查询:

SELECT  tch1.WeekEndingDate AS WeekEndingDate, 
        tch1.TotalHoursWorked AS TotalHoursWorked, 
        e.ID AS ID, 
        e.FirstName AS FirstName, 
        e.PTORemaining AS PTORemaining, 
        so1.Name AS Name, 
        Extent5.Name AS Name1, 
        e.FirstName + N' ' + e.LastName AS C1, 
        tch2.WeekEndingDate AS WeekEndingDate1, 
        tch2.TotalHoursWorked AS TotalHoursWorked1
FROM dbo.TimeCardHeader AS tch1
INNER JOIN dbo.Employee AS e ON tch1.EmployeeID = e.ID
INNER JOIN dbo.StatusOption AS so1 ON tch1.CurrentStatusID = so1.ID
LEFT OUTER JOIN dbo.TimeCardHeader AS tch2 ON tch1.EmployeeID = tch2.EmployeeID
INNER JOIN dbo.StatusOption AS Extent5 ON tch2.CurrentStatusID = Extent5.ID
WHERE (tch1.WeekEndingDate = '9/24/2016' AND tch2.WeekEndingDate = '10/1/2016' AND e.ID = 80)
OR (tch1.WeekEndingDate = '9/24/2016' AND tch2.WeekEndingDate = '10/1/2016' AND e.ManagerID = 80);
对于每个,
WeekEndingDate
我尝试使用
WeekEndingDate=COALESCE('9/24/2016',NULL)


使用
COALESCE
是正确的做法,而我只是用错了,或者我应该在这里使用另一种方法,以便即使没有周日期为'10/1/2016'的TimeCardHeader,我也可以得到结果。

从我所见,您的内部加入状态选项基于TimeCarder(tch2)的CurrentStatusID,这是一个左加入。如果tch2中没有行,那么内部联接将以您正在经历的结果结束。有没有一种方法可以使StatusOption join(Extent5)成为左连接,并将您的where与您已经尝试过的coalesce/isnull结合起来?

从我所看到的,您的内部连接到StatusOption是基于TimeCarder(tch2)的CurrentStatusID,这是一种左连接。如果tch2中没有行,那么内部联接将以您正在经历的结果结束。有没有一种方法可以使StatusOption join(Extent5)成为左连接,并将where与已经尝试过的coalesce/isnull结合起来?

coalesce()
无法解决此问题。现在,您的WHERE语句可以在不更改以下内容的情况下重写:

 WHERE tch1.WeekEndingDate = '9/24/2016' AND tch2.WeekEndingDate = '10/1/2016' AND (e.ID = 80 OR e.ManagerID = 80)
这更容易理解。要引入
tch2.WeekEndingDate
10/1/2016
或为空的记录,您只需在此简化版本中添加:

 WHERE tch1.WeekEndingDate = '9/24/2016' AND (tch2.WeekEndingDate = '10/1/2016' OR tch2.WeekEndingDate IS NULL) AND (e.ID = 80 OR e.ManagerID = 80)
也可以写为:

 WHERE tch1.WeekEndingDate = '9/24/2016' AND tch2.WeekEndingDate IN ('10/1/2016',NULL) AND (e.ID = 80 OR e.ManagerID = 80)
此外,正如注释中提到的@a_horse_和_no_名称一样,您可以将WHERE子句设置为: 其中tch1.WeekEndingDate='9/24/2016'和(e.ID=80或e.ManagerID=80)

并将左侧外部联接的启用状态更改为:

LEFT OUTER JOIN dbo.TimeCardHeader AS tch2 ON tch1.EmployeeID = tch2.EmployeeID AND tch2.WeekEndingDate = '10/01/2016'
这将删除tch2加入之前的所有记录,这些记录没有2016年1月10日的
WeekEndingDate

COALESCE()
无法解决此问题。现在,您的WHERE语句可以在不更改以下内容的情况下重写:

 WHERE tch1.WeekEndingDate = '9/24/2016' AND tch2.WeekEndingDate = '10/1/2016' AND (e.ID = 80 OR e.ManagerID = 80)
这更容易理解。要引入
tch2.WeekEndingDate
10/1/2016
或为空的记录,您只需在此简化版本中添加:

 WHERE tch1.WeekEndingDate = '9/24/2016' AND (tch2.WeekEndingDate = '10/1/2016' OR tch2.WeekEndingDate IS NULL) AND (e.ID = 80 OR e.ManagerID = 80)
也可以写为:

 WHERE tch1.WeekEndingDate = '9/24/2016' AND tch2.WeekEndingDate IN ('10/1/2016',NULL) AND (e.ID = 80 OR e.ManagerID = 80)
此外,正如注释中提到的@a_horse_和_no_名称一样,您可以将WHERE子句设置为: 其中tch1.WeekEndingDate='9/24/2016'和(e.ID=80或e.ManagerID=80)

并将左侧外部联接的启用状态更改为:

LEFT OUTER JOIN dbo.TimeCardHeader AS tch2 ON tch1.EmployeeID = tch2.EmployeeID AND tch2.WeekEndingDate = '10/01/2016'

这将删除tch2加入前的所有记录,这些记录没有2016年1月10日的
WeekEndingDate

将与tch2相关的谓词移动到join子句中:-

SELECT  tch1.WeekEndingDate AS WeekEndingDate, 
        tch1.TotalHoursWorked AS TotalHoursWorked, 
        e.ID AS ID, 
        e.FirstName AS FirstName, 
        e.PTORemaining AS PTORemaining, 
        so1.Name AS Name, 
        Extent5.Name AS Name1, 
        e.FirstName + N' ' + e.LastName AS C1, 
        tch2.WeekEndingDate AS WeekEndingDate1, 
        tch2.TotalHoursWorked AS TotalHoursWorked1
FROM dbo.TimeCardHeader AS tch1
INNER JOIN dbo.Employee AS e ON tch1.EmployeeID = e.ID
INNER JOIN dbo.StatusOption AS so1 ON tch1.CurrentStatusID = so1.ID
LEFT OUTER JOIN dbo.TimeCardHeader AS tch2 ON tch1.EmployeeID = tch2.EmployeeID 

    AND tch2.WeekEndingDate = '10/1/2016'

INNER JOIN dbo.StatusOption AS Extent5 ON tch2.CurrentStatusID = Extent5.ID
WHERE (tch1.WeekEndingDate = '9/24/2016'  AND e.ID = 80)
OR (tch1.WeekEndingDate = '9/24/2016' AND e.ManagerID = 80);

如果where子句中有它们,则会将连接的行全部过滤掉。

将与tch2相关的谓词移动到join子句中:-

SELECT  tch1.WeekEndingDate AS WeekEndingDate, 
        tch1.TotalHoursWorked AS TotalHoursWorked, 
        e.ID AS ID, 
        e.FirstName AS FirstName, 
        e.PTORemaining AS PTORemaining, 
        so1.Name AS Name, 
        Extent5.Name AS Name1, 
        e.FirstName + N' ' + e.LastName AS C1, 
        tch2.WeekEndingDate AS WeekEndingDate1, 
        tch2.TotalHoursWorked AS TotalHoursWorked1
FROM dbo.TimeCardHeader AS tch1
INNER JOIN dbo.Employee AS e ON tch1.EmployeeID = e.ID
INNER JOIN dbo.StatusOption AS so1 ON tch1.CurrentStatusID = so1.ID
LEFT OUTER JOIN dbo.TimeCardHeader AS tch2 ON tch1.EmployeeID = tch2.EmployeeID 

    AND tch2.WeekEndingDate = '10/1/2016'

INNER JOIN dbo.StatusOption AS Extent5 ON tch2.CurrentStatusID = Extent5.ID
WHERE (tch1.WeekEndingDate = '9/24/2016'  AND e.ID = 80)
OR (tch1.WeekEndingDate = '9/24/2016' AND e.ManagerID = 80);

如果where子句中包含这些行,则将过滤掉所有连接的行。

COALESCE返回第一个非空值。将
null
作为COALESCE的最后一个参数的原因是什么?如果tch2没有任何行,那么
和tch2.column='whatever'
将为false。您是否尝试过将其更改为类似于
和tch2.column为NULL或tch2.column='which'
?外部联接表上的
其中
条件将外部联接转换为内部联接。您需要将其移动到
join
条件下(退出
中的
)@a_horse_与_no_name尝试了该操作,但仍然返回了0个结果。COALESCE返回第一个非空值。将
null
作为COALESCE的最后一个参数的原因是什么?如果tch2没有任何行,那么
和tch2.column='whatever'
将为false。您是否尝试过将其更改为类似于
和tch2.column为NULL或tch2.column='which'
?外部联接表上的
其中
条件将外部联接转换为内部联接。您需要将其移动到
加入
条件下(退出
where
)@a_horse_和_no_name尝试了该操作,仍然返回了0个结果。我已尝试更新我的where close to do
或tch2。WeekEndingDate为NULL
,但仍然没有返回任何结果,然后我尝试更新整个select以按照建议更改
左外部联接
,但仍然没有返回任何结果。问题与左外部联接无关。也许,让外部联接单独存在,从WHERE语句中删除所有限制,看看是否可以找到任何符合要求的记录。我猜你什么也找不到。可能问题在于您的内部联接之一,或者您没有符合要求的数据。问题在于,目前还没有日期为“10/1/2016”的记录,但我对
左侧外部联接的理解是,因为没有可返回右侧的记录(10/1/2016)它仍然会返回左侧,但会为右侧返回null。我需要精心设计SQL,这样当左边没有记录时,我会得到空值。对,所以您将限制从WHERE子句移动到左边外部联接的
上的
,但仍然没有记录。这意味着
WHERE
子句中的其他限制导致没有记录返回。在这一点上,它100%与您的左联接表无关。你的问题在你陈述的其他地方。从WHERE子句中删除其余的限制,看看您是否能够找出您为什么要使用ge