我有一个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
正确的事情,我只是错误地使用它,或者我应该在这里使用另一种方法,以便即使没有TimeCardHeader,其WeekEndingDate为“10/1 / 2016'我可以得到结果。
答案 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子句中有它们,那么你将完全过滤掉连接的行。