当不存在行时,LEFT JOIN不返回null

atmip9wb  于 2022-10-22  发布在  其他
关注(0)|答案(3)|浏览(171)

我正在处理两个表:一个表处理一组人的基本人口统计数据,另一个表则处理已完成的活动。我需要做的是从人口统计表中提取所有结果(所有人),然后显示在给定时间段内完成特定类型活动的任何人的活动信息(也有可能一个人在该时间段内已经完成了多个活动)。如果一个人没有完成任何指定的活动,我仍然希望他们在列表中可见。我希望结果如下:

PersonID  Name           DateOfBirth   ActivityDate   ActivityType
---------------------------------------------------------------------
1001      John Smith     01/01/1990    10/18/2022     Painting
1002      Jane Doe       12/31/1980    NULL           NULL
1003      Bob Brown      07/04/1995    10/17/2022     Reading
1003      Bob Brown      07/04/1995    09/09/2022     Painting
1004      Mike Jones     03/24/1984    NULL           NULL
1005      Ann Green      11/30/1988    08/29/2022     Writing
1006      Sally Black    05/15/1999    NULL           NULL

看起来这应该是一个非常简单的查询,两个表之间有一个LEFT JOIN

SELECT DISTINCT
    d.PersonID,
    d.Name
    d.DateOfBirth,
    a.ActivityDate
    a.ActivityType
FROM Demographics d
LEFT JOIN Activity a ON d.PersonID = a.PersonID
WHERE ActivityDate BETWEEN DATEADD(yy,-1,GETDATE()) AND GETDATE()
    AND ActivityType IN ('Painting','Reading','Writing')
ORDER BY d.PersonID, a.ActivityDate DESC

但是,当我运行此查询时,我只得到实际完成活动的人的结果(即,我的示例中缺少NULL结果的人)。

PersonID  Name           DateOfBirth   ActivityDate   ActivityType
---------------------------------------------------------------------
1001      John Smith     01/01/1990    10/18/2022     Painting
1003      Bob Brown      07/04/1995    10/17/2022     Reading
1003      Bob Brown      07/04/1995    09/09/2022     Painting
1005      Ann Green      11/30/1988    08/29/2022     Writing

同样,我希望显示人口统计表中的所有人,但随后显示完成这些活动的人的指定活动。
我的加入有什么问题吗?LEFT JOIN是正确的方法吗?

6jygbczu

6jygbczu1#

WHERE子句完全基于左联接(Activity)表,并且在WHERE语句中的任何位置都不允许使用NULL值。因此,连接正在工作,但您正在过滤出没有活动的任何行。
要更正此问题,请更改

WHERE ActivityDate BETWEEN DATEADD(yy,-1,GETDATE()) AND GETDATE()
    AND ActivityType IN ('Painting','Reading','Writing')

WHERE a.PersonId IS NULL 
OR (
    ActivityDate BETWEEN DATEADD(yy,-1,GETDATE()) AND GETDATE()
    AND ActivityType IN ('Painting','Reading','Writing')
)
sshcrbum

sshcrbum2#

添加条件时
ActivityType IN ('Painting','Reading','Writing')
实际上,你禁止使用ActivityTypeNULL,这对于那些没有完成任何活动的人来说是必要的。与ActivityDate上的条件相同
按如下方式更改查询,以允许NULL

SELECT DISTINCT
    d.PersonID,
    d.Name
    d.DateOfBirth,
    a.ActivityDate
    a.ActivityType

FROM Demographics d LEFT JOIN Activity a ON d.PersonID = a.PersonID
WHERE (ActivityDate IS NULL OR ActivityDate BETWEEN DATEADD(yy,-1,GETDATE()) AND GETDATE())
AND (ActivityType IS NULL OR ActivityType IN ('Painting','Reading','Writing'))
ORDER BY d.PersonID, a.ActivityDate DESC
xfb7svmp

xfb7svmp3#

将ActivityType列中的“OR”用于现有查询中的“null”记录,如下所示:

SELECT DISTINCT
    d.PersonID,
    d.Name,
    d.DateOfBirth,
    a.ActivityDate,
    a.ActivityType
FROM Demographics d
LEFT JOIN Activity a ON d.PersonID = a.PersonID
WHERE ActivityDate BETWEEN DATEADD(yy,-1,GETDATE()) AND GETDATE()
AND (ActivityType IN ('Painting','Reading','Writing') OR ActivityType  IS NULL)
ORDER BY d.PersonID, a.ActivityDate DESC

相关问题