Sql server 当第二个表没有值时,左外部联接不返回结果
我有一个SELECT语句,它有一个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,
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