SQL左连接不包括左表中的所有记录
Posted
技术标签:
【中文标题】SQL左连接不包括左表中的所有记录【英文标题】:SQL left join is not including all records from left table 【发布时间】:2021-04-27 11:32:37 【问题描述】:我需要获取每个员工在不同任务上的每月总工作时数。为此,我正在编写一个存储过程。但是左连接没有填充员工表中的所有记录。 我知道 where 条件过滤掉了 null 值,但我真的不知道如何克服这个问题。
ALTER PROCEDURE [dbo].[GetEmployeeWorkHours]
@PageSize smallint = 10,
@CurrentPage smallint = 1,
@EmployeeId varchar(1000) = null,
@StartDate datetime = null,
@EndDate datetime = null
AS
BEGIN
if(@StartDate is null)
select @StartDate = DATEADD(month, DATEDIFF(month, 0, getDate()), 0)
if(@EndDate is null)
select @EndDate = getDate()
select e.Id,
e.FirstName + ' ' + e.LastName as [Name],
sum([Minutes]/60.0) as [WorkedHours]
from Employees e
left join TaskResources tr on (e.Id = tr.EmployeeId)
inner join ResourceTaskSchedules rts on (tr.Id = rts.TaskResourceId)
inner join TaskTimeSheets tts on (rts.Id = tts.ResourceTaskScheduleId)
where
((@EmployeeId is null) or (e.Id in (select splitdata from dbo.SplitEmployeeIds(@EmployeeId, ',')))) and
cast(tts.CheckIn as date) >= @StartDate
and cast(tts.CheckIn as date) <= @EndDate
group by
e.Id
ORDER BY
e.Id
OFFSET (@CurrentPage-1)*@PageSize ROWS
FETCH NEXT @PageSize ROWS ONLY;
结束
【问题讨论】:
【参考方案1】:在from
子句中使用left join
后,通常会继续使用left join
。如果第二个表用于任何条件,这一点至关重要。
然后,任何左连接表上的任何过滤条件都需要在on
子句中,而不是where
子句中。所以:
from Employees e left join
TaskResources tr
on e.Id = tr.EmployeeId left join
ResourceTaskSchedules rts
on tr.Id = rts.TaskResourceId left join
TaskTimeSheets tts
on rts.Id = tts.ResourceTaskScheduleId and
cast(tts.CheckIn as date) >= @StartDate and
cast(tts.CheckIn as date) <= @EndDate
where ((@EmployeeId is null) or
(e.Id in (select splitdata from dbo.SplitEmployeeIds(@EmployeeId, ','))))
【讨论】:
它现在给了我正确的结果,谢谢 Gordon-Linoff以上是关于SQL左连接不包括左表中的所有记录的主要内容,如果未能解决你的问题,请参考以下文章