如果连接表缺少该日期的记录,则在SQL中返回NULL

时间:2010-02-04 14:11:22

标签: sql sql-server

早安全部。我一直在努力解决这个问题,我似乎无法绕过它。

所以我的数据库中有两个表

tblDateTrans

CREATE TABLE [dbo].[tblDateTrans](
    [Date] [smalldatetime] NOT NULL,
) 

此表是一个外部日历表,其中包含2007年1月1日至2011年1月1日的所有日期,它还包含假日信息,公司期间等附加信息。但这对此并不重要问题

我的第二张表是

    tblSurveySession
    CREATE TABLE [dbo].[tblSurveySession](
        [surveySessionID] [int] IDENTITY(1,1) NOT NULL,
        [guestID] [int] NULL,
        [surveyID] [int] NOT NULL,
        [FK_StoreId] [int] NULL,
        [surveyCompletedDate] [datetime] NULL
)

此表包含我们的客人在一段时间内发出并完成的调查列表。 FK_StoreId是公司的业务单位ID,surveyCompletedDate仅包含日期,没有时间。

我的目标是在tblDateTrans表上使用LEFT OUTER JOIN返回surveySessionID和Dates的列表,我想返回所有日期,无论是否有值。所以我试着运行这个查询:

SELECT     tblDateTrans.Date, dbo.tblSurveySession.surveySessionID, dbo.tblSurveySession.FK_StoreId
FROM         OPENQUERY([APOLLO], 'select Date FROM apollo.nhcglobal.dbo.tblDateTrans') AS tblDateTrans LEFT OUTER JOIN
                      dbo.tblSurveySession ON tblDateTrans.Date = dbo.tblSurveySession.surveyCompletedDate
WHERE     (tblDateTrans.Date >= '1/1/2010') AND (tblDateTrans.Date <= '2/1/2010') AND (dbo.tblSurveySession.FK_StoreId = 4)

我的返回数据如下:

Date                    surveySessionID     FK_StoreId
2010-01-01 00:00:00.000     12702           4
2010-01-01 00:00:00.000     12736           4
2010-01-01 00:00:00.000     12456           4
2010-01-03 00:00:00.000     12662           4
2010-01-04 00:00:00.000     12660           4
2010-01-05 00:00:00.000     12510           4
2010-01-05 00:00:00.000     12889           4
2010-01-24 00:00:00.000     13751           4
2010-01-25 00:00:00.000     13793           4
2010-01-28 00:00:00.000     13958           4
2010-01-30 00:00:00.000     14059           4
2010-01-31 00:00:00.000     14139           4

我的目标是让查询返回如下数据:

Date                    surveySessionID     FK_StoreId
2010-01-01 00:00:00.000     12702           4
2010-01-01 00:00:00.000     12736           4
2010-01-01 00:00:00.000     12456           4
2010-01-02 00:00:00.000     NULL            NULL
2010-01-03 00:00:00.000     12662           4
2010-01-04 00:00:00.000     12660           4
2010-01-05 00:00:00.000     12510           4
2010-01-05 00:00:00.000     12889           4
2010-01-06 00:00:00.000     NULL            NULL
2010-01-07 00:00:00.000     NULL            NULL
2010-01-08 00:00:00.000     NULL            NULL
2010-01-09 00:00:00.000     NULL            NULL
2010-01-10 00:00:00.000     NULL            NULL
2010-01-11 00:00:00.000     NULL            NULL
2010-01-12 00:00:00.000     NULL            NULL
2010-01-13 00:00:00.000     NULL            NULL
2010-01-14 00:00:00.000     NULL            NULL
2010-01-15 00:00:00.000     NULL            NULL
2010-01-16 00:00:00.000     NULL            NULL
2010-01-17 00:00:00.000     NULL            NULL
2010-01-18 00:00:00.000     NULL            NULL
2010-01-19 00:00:00.000     NULL            NULL
2010-01-20 00:00:00.000     NULL            NULL
2010-01-21 00:00:00.000     NULL            NULL
2010-01-22 00:00:00.000     NULL            NULL
2010-01-23 00:00:00.000     NULL            NULL
2010-01-24 00:00:00.000     13751           4
2010-01-25 00:00:00.000     13793           4
2010-01-28 00:00:00.000     13958           4
2010-01-30 00:00:00.000     14059           4
2010-01-31 00:00:00.000     14139           4

我认为LEFT OUTER JOIN会强制查询查看所有日期,并在缺少surveySessionIDs和FK_StoreIds的日期返回NULLS。我们之前遇到过这类问题,因此解决这个问题对我们未来将是一个巨大的帮助。谢谢大家的帮助!

3 个答案:

答案 0 :(得分:4)

(dbo.tblSurveySession.FK_StoreId = 4)从WHERE移动到LEFT JOIN的ON子句,如:

LEFT OUTER JOIN dbo.tblSurveySession ON tblDateTrans.Date = dbo.tblSurveySession.surveyCompletedDate AND dbo.tblSurveySession.FK_StoreId = 4

答案 1 :(得分:2)

由于你的WHERE子句,你正在过滤掉你想要的一些行。尝试更改WHERE子句的最后一部分以允许NULL,即:

AND (dbo.tblSurveySession.FK_StoreId = 4)

到此:

AND (dbo.tblSurveySession.FK_StoreId = 4 OR
     dbo.tblSurveySession.FK_StoreId IS NULL)

答案 2 :(得分:2)

反转连接方向

SELECT tblDateTrans.Date, dbo.tblSurveySession.surveySessionID, dbo.tblSurveySession.FK_StoreId
FROM   OPENQUERY([APOLLO], 'select Date FROM apollo.nhcglobal.dbo.tblDateTrans') AS tblDateTrans 
LEFT OUTER JOIN dbo.tblSurveySession 
    ON tblDateTrans.Date = dbo.tblSurveySession.surveyCompletedDate
    AND (dbo.tblSurveySession.FK_StoreId = 4)
WHERE (tblDateTrans.Date >= '1/1/2010') AND (tblDateTrans.Date <= '2/1/2010')