Возврат значений NULL в SQL, если в объединенной таблице отсутствуют записи на эту дату - PullRequest
3 голосов
/ 04 февраля 2010

Доброе утро всем. Я боролся с этой проблемой некоторое время, и я не могу обернуться вокруг нее.

Итак, у меня есть две таблицы в моей базе данных

tblDateTrans

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

Эта таблица является внешней календарной таблицей, которая содержит все даты с 01.01.2007 по 01.01.2011, а также содержит дополнительную информацию, такую ​​как информация о праздниках, период компании и т. Д. Но это не важно для этого вопрос.

Мой второй стол -

    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 - это идентификатор бизнес-единицы для компании, а surveyCompletedDate содержит только даты, но не время.

Моя цель - вернуть список surveySessionIDs и Dates, используя LEFT OUTER JOIN в таблице tblDateTrans. Я хотел бы вернуть все даты независимо от наличия значений. Поэтому я попытался выполнить этот запрос:

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 заставит запрос просмотреть все даты и вернуть NULLS в дни, в которых отсутствуют surveySessionIDs и FK_StoreIds. Мы сталкивались с подобными проблемами раньше, когда работали с другими проектами, поэтому их решение в будущем нам очень поможет. Спасибо всем за помощь!

Ответы [ 3 ]

4 голосов
/ 04 февраля 2010

переместите (dbo.tblSurveySession.FK_StoreId = 4) из WHERE в предложение ON LEFT JOIN, как:

LEFT OUTER JOIN dbo.tblSurveySession ON tblDateTrans.Date = dbo.tblSurveySession.surveyCompletedDate AND dbo.tblSurveySession.FK_StoreId = 4
2 голосов
/ 04 февраля 2010

инвертировать направление соединения

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') 
2 голосов
/ 04 февраля 2010

Вы отфильтровываете некоторые строки, которые хотите, из-за вашего предложения WHERE. Попробуйте изменить последнюю часть вашего предложения WHERE, чтобы также разрешить NULL, т. Е. Из этого:

AND (dbo.tblSurveySession.FK_StoreId = 4)

к этому:

AND (dbo.tblSurveySession.FK_StoreId = 4 OR
     dbo.tblSurveySession.FK_StoreId IS NULL)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...