2013-04-23 2 views
0

У меня есть таблица, которая содержит несколько записей для нескольких дат.Полное внешнее соединение, не возвращающее все строки?

Я пытаюсь увидеть разницу между «датой 1» и «датой 2», и мое полное внешнее соединение не возвращает данные, которые я ожидал.

Я знаю, что есть 13278 строк на дату 1 и 13282 на дату 2 - поэтому я ожидаю увидеть не менее 13282 строк, но я вернусь 13195 ..., который является INNER JOIN (я проверил это).

Я надеюсь на результаты как:

001  00NULL 1000 
001  000124 009 1000 1000 
001  000125 009 1000 1000 
001  000126 009 1000 NULL 

, но это не получают какой-либо из нулевых строк с обеих сторон?

SELECT 
    COALESCE(c.AccountBranch, p.AccountBranch) 
    , COALESCE(c.AccountNumber, p.AccountNumber) 
    , COALESCE(c.AccountSuffix, p.AccountSuffix) 
    , c.PrincipleAmount 
    , p.PrincipleAmount 
    FROM ADStaging..cb_account_extension_principle_dpd c 
    FULL OUTER JOIN ADStaging..cb_account_extension_principle_dpd p 
     ON p.AccountBranch = c.AccountBranch 
     AND p.AccountNumber = c.AccountNumber 
     AND p.AccountSuffix = c.AccountSuffix 
WHERE 
    (c.BusinessDataDate IS NULL OR c.BusinessDataDate = @CurrentBusinessDataDate) 
    AND 
    (p.BusinessDataDate IS NULL OR p.BusinessDataDate = @PreviousBusinessDataDate) 

Это работает - объединение «ключ» для объединения двух отдельных выбранных утверждений?

SELECT 
     COALESCE(C.Account, P.Account) AS Account 
    , COALESCE(C.AccountBranch, P.AccountBranch) as AccountBranch 
    , COALESCE(C.AccountNumber, P.AccountNumber) as AccountNumber 
    , COALESCE(C.AccountSuffix, P.AccountSuffix) as AccountSuffix 
    , P.PrincipleAmount AS PreviousAmount 
    , C.PrincipleAmount AS CurrentAmount 
    , ISNULL(C.PrincipleAmount, P.PrincipleAmount) - ISNULL(P.PrincipleAmount,0) 
FROM 
(SELECT 
    (pd.AccountBranch + pd.AccountNumber + pd.AccountSuffix) AS Account 
    , pd.AccountBranch 
    , pd.AccountNumber 
    , pd.AccountSuffix 
    , pd.PrincipleAmount 
FROM ADStaging..cb_account_extension_principle_dpd pd 
WHERE pd.BusinessDataDate = @CurrentBusinessDataDate) C 
FULL OUTER JOIN 
(SELECT 
    (pd.AccountBranch + pd.AccountNumber + pd.AccountSuffix) AS Account 
    , pd.AccountBranch 
    , pd.AccountNumber 
    , pd.AccountSuffix 
    , pd.PrincipleAmount 
FROM ADStaging..cb_account_extension_principle_dpd pd 
WHERE pd.BusinessDataDate = @PreviousBusinessDataDate) P 
    ON P.Account = C.Account 
WHERE 
    (P.PrincipleAmount IS NULL OR C.PrincipleAmount IS NULL) 
    OR 
    P.PrincipleAmount <> C.PrincipleAmount 

Но это не делает - вступление на объединенные ценности - только тогда, когда они являются отдельные таблицы?

SELECT 
    COALESCE(c.AccountBranch, p.AccountBranch) 
    , COALESCE(c.AccountNumber, p.AccountNumber) 
    , COALESCE(c.AccountSuffix, p.AccountSuffix) 
    , c.PrincipleAmount 
    , p.PrincipleAmount 
    FROM ADStaging..cb_account_extension_principle_dpd c 
    FULL OUTER JOIN ADStaging..cb_account_extension_principle_dpd p 
     ON (p.AccountBranch + p.AccountNumber + p.AccountSuffix) 
     = (c.AccountBranch + c.AccountNumber + c.AccountSuffix) 
WHERE 
    (c.BusinessDataDate = @CurrentBusinessDataDate) 
    AND 
    (p.BusinessDataDate = @PreviousBusinessDataDate) 
+0

План выполнения показывает это как выполнение INNER JOIN ??? Теперь очень смутно! – BlueChippy

+0

Условие, в котором убивает внешнее соединение. – Paparazzi

ответ

0

Я думаю, ваша проблема заключается в том, что в первом запросе дата не является частью матча. В вашем втором запросе два набора, которые вы соединяете, фильтруются по дате уже, поэтому он имитирует, что произойдет, если вы сравните дату. Скажем, у вас есть одна учетная запись, номер, суффикс дважды, но для разных дат! Это означало бы, что полное внешнее соединение находит совпадение, так как у вас нет даты в ON-clause.

Попробуйте это:

use ADStaging; 
--your dates go here: 
declare @CurrentBusinessDataDate date = '2013-04-21' 
, @PreviousBusinessDataDate date = '2013-04-23'; 
SELECT 
COALESCE(c.AccountBranch, p.AccountBranch) 
, COALESCE(c.AccountNumber, p.AccountNumber) 
, COALESCE(c.AccountSuffix, p.AccountSuffix) 
, c.PrincipleAmount 
, p.PrincipleAmount 

FROM cb_account_extension_principle_dpd AS c 
FULL OUTER JOIN cb_account_extension_principle_dpd AS p 
    ON p.AccountBranch = c.AccountBranch 
    AND p.AccountNumber = c.AccountNumber 
    AND p.AccountSuffix = c.AccountSuffix 
    AND p.BusinessDataDate = @PreviousBusinessDataDate 
    AND c.BusinessDataDate = @CurrentBusinessDataDate; 
+0

Это именно то, чего я не хочу! lol Я не хочу, чтобы даты были одинаковыми ... Я хочу разницу между date1 и date2 - они никогда не могут быть одинаковыми, поэтому объединение на них возвращает нулевые строки. – BlueChippy

+0

Некоторые образцы данных были бы замечательными, тогда спасибо! Предпочтительно на sqlfiddle.com. –

+0

Я сделал немного мозгового кода в коде для дат. Я обновил его, чтобы соответствовать тому, что я на самом деле думал, что вы хотите (и это соответствует тому, что я на самом деле заявил выше кода!) Попробуйте сейчас. –

8

где убивает внешнее соединение.
Столбец не может быть как null, так и = значением.
Поместите условия в соединение.

SELECT COALESCE(c.AccountBranch, p.AccountBranch) 
    , COALESCE(c.AccountNumber, p.AccountNumber) 
    , COALESCE(c.AccountSuffix, p.AccountSuffix) 
    , c.PrincipleAmount, p.PrincipleAmount 
FROM   cb_account_extension_principle_dpd c 
FULL OUTER JOIN cb_account_extension_principle_dpd p 
    ON p.AccountBranch = c.AccountBranch 
AND p.AccountNumber = c.AccountNumber 
AND p.AccountSuffix = c.AccountSuffix 
AND c.BusinessDataDate = @CurrentBusinessDataDate 
AND p.BusinessDataDate = @PreviousBusinessDataDate 
+0

Зачем нужно p.AccountNumber = c.AccountSuffix и p.AccountSuffix = c.AccountNumber? Это выглядит в обратном направлении. –

+0

@ DavidSöderlund исправлено, спасибо – Paparazzi

Смежные вопросы