当第二个表没有值时,LEFT OUTER JOIN不返回结果

时间:2016-09-26 18:25:53

标签: sql-server join

我有一个SELECT语句,其LEFT OUTTER JOIN会导致表连接到自身。我遇到的问题是,当连接的右侧没有结果时,整个查询不会重新调整结果。我认为这是由于我的WHERE条款,但我尝试将COALESCENULL一起用作第二个值,但没有得到任何结果。

这是我的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正确的事情,我只是错误地使用它,或者我应该在这里使用另一种方法,以便即使没有TimeCardHeader,其WeekEndingDate为“10/1 / 2016'我可以得到结果。

3 个答案:

答案 0 :(得分:1)

从我所看到的,您对StatusOption的内部联接基于来自TimeCardHolder(tch2)的CurrentStatusID,这是一个左连接。如果tch2中没有行,则内部联接将以您遇到的结果结束。有没有办法让StatusOption连接(Extent5)成为一个左连接,并将你的where与你已经尝试过的coalesce / isnull结合起来?

答案 1 :(得分:1)

//captured the form data in variable $user= mysql_real_escape_string($_POST['user']); $message= mysql_real_escape_string($_POST['message']); $sql = "INSERT INTO testmessage2 (user, message) VALUES('$user','$message')"; 不会解决这个问题。现在你的WHERE语句可以被重写而不需要改变:

COALESCE()

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

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)

此外,如注释中提到的@a_horse_with_no_name,您可以将WHERE子句设置为:           在哪里tch1.WeekEndingDate ='9/24/2016'AND(e.ID = 80或e.ManagerID = 80)

将LEFT OUTER JOIN的ON更改为:

 WHERE tch1.WeekEndingDate = '9/24/2016' AND tch2.WeekEndingDate IN ('10/1/2016',NULL) AND (e.ID = 80 OR e.ManagerID = 80)

这将删除tch2之前的所有记录,但没有LEFT OUTER JOIN dbo.TimeCardHeader AS tch2 ON tch1.EmployeeID = tch2.EmployeeID AND tch2.WeekEndingDate = '10/01/2016' 的{​​{1}}

答案 2 :(得分:0)

将与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子句中有它们,那么你将完全过滤掉连接的行。