如果添加了WHERE子句,则LEFT JOIN不返回结果吗?

时间:2019-12-25 19:46:40

标签: sql sql-server tsql

DECLARE @ps_StartDate DATETIME = '20190101'
      , @ps_EndDate   DATETIME = '20191224'
      , @ps_COMPANYNO VARCHAR(20) = '01'

SET @ps_EndDate = DATEADD(dd, 1, @ps_EndDate)

SELECT
    CASE WHEN @ps_COMPANYNO IN ('01') THEN 'YS45J146'
        ELSE 'YS45J147'
    END                                 AS 'Client ID'
    ,e.EMPNO                            AS 'WORKER ID'
    ,''                                 AS 'Org'
    ,''                                 AS 'Job Number'
    ,'Regular'                          AS 'Pay Component'
    ,''                                 AS 'Rate'
    ,''                                 AS 'Rate Number'
    ,SUM(t.TIMEBILLED + (ISNULL(ehrs.AllocationDays, 0) * 24))                  AS 'Hours'
    ,''                                 AS 'Units'
    ,''                                 AS 'Line Date'
    ,''                                 AS 'Amount'
    ,''                                 AS 'Check Seq Number'
    ,''                                 AS 'Override State'
    ,''                                 AS 'Override Local'
    ,''                                 AS 'Override Local Jurisdiction'
    ,''                                 AS 'Labor Assignment'
FROM TIMEBILL t (NOLOCK)
INNER JOIN EMPLOYEE e (NOLOCK) ON t.USERID = e.USERID
LEFT JOIN dbo.EmpHRSchedule ehrs (NOLOCK) ON (e.EmployeeNo = ehrs.EmployeeNo)
WHERE t.PRTID = 'P'
    AND t.DATE >= @ps_StartDate
    AND t.DATE < @ps_EndDate
    AND ehrs.STARTDATE >= @ps_StartDate
    AND ehrs.STARTDATE < @ps_EndDate
    AND e.COMPANYNO = @ps_COMPANYNO
    AND t.SUBCAT <> 'LUNCH'
    AND t.WAGETYPE <> 'OVERTIME'
    AND e.SALARYUNIT = 'HOURLY'
    --AND ehrs.Type = 'HOLIDAY'
GROUP BY e.EMPNO

我试图仅将dbo.EmpHRSchedule.Type ='HOLIDAY'条目添加到“小时”列中(如果存在)。据我了解,LEFT JOIN仅在匹配时才返回条目,对于不匹配则返回NULL。当我取消对AND ehrs.Type = 'HOLIDAY'行的注释时,根本不会返回任何结果。

为什么会这样?我还有另一种方法可以对dbo.Timebill.Timebilled和dbo.EmpHRSchedule.AllocationDays(如果存在)求和吗?

1 个答案:

答案 0 :(得分:3)

包括以下内容:

AND ehrs.Type = 'HOLIDAY'

WHERE子句中,您实际上得到了INNER联接而不是LEFT联接,因为您仅从表ers中获得匹配的行,而没有得到任何ehrs.Type将是NULL的不匹配行。
您可以做的就是将条件移到ON连接的LEFT子句中:

LEFT JOIN dbo.EmpHRSchedule ehrs (NOLOCK) 
ON (e.EmployeeNo = ehrs.EmployeeNo) AND ehrs.Type = 'HOLIDAY' 

,您还可以为同一张表添加其他条件:

LEFT JOIN dbo.EmpHRSchedule ehrs (NOLOCK) 
ON (e.EmployeeNo = ehrs.EmployeeNo) AND ehrs.Type = 'HOLIDAY' 
   AND ehrs.STARTDATE >= @ps_StartDate
   AND ehrs.STARTDATE < @ps_EndDate