Полное внешнее соединение не возвращает несопоставленные значения поля соединения SQL SERVER 2005 - PullRequest
1 голос
/ 22 ноября 2011

Я использую приведенный ниже код для расчета заработанной премии по страховке (автомобилю) за данный месяц, в данном случае это сентябрь. Код выполняет вычитание общей заработанной премии за все время до 30 сентября за вычетом общей заработанной премии за все время до 31 августа, чтобы вернуть премию, заработанную только за сентябрь.

Результаты выглядят примерно так:

eprem        coveragecode  
0.0211       AD  
277970.8291  BI  
245700.6741  COLL  
86997.5694   COMP  
85.0083      CustomParts  
848.7873     Death  
0.00         ECL  
0.00         GPIP  
692.3802     Income  
2410.5513    MED  
267670.1099  PD  
387628.504   PIP  
26.8767      PU  
11736.2762   Rental  
4304.3367    Towing   
4211.2574    UIMBI  
19804.8964   UMBI  
15145.3211   UMPD  

Когда я складываю премию для всех покрытий, я получаю 1325233.399, что является точной точной суммой премии, заработанной за сентябрь.

Теперь я пытаюсь добавить в результат поле почтового индекса. Если я запускаю приведенный ниже код без столбца zipcode, указанного где-либо в коде, то я получаю приведенный выше результат, который является правильным, но когда я добавляю столбец zipcode, я возвращаю тысячи ожидаемых строк, но когда я складываю общую премию, я получаю 1323608,401 вместо 1325233,399, что является правильным итогом. Я полагаю, что происходит то, что существуют определенные комбинации покрытия и почтового индекса (к которым я присоединился к моим 2 производным таблицам), которые существуют в одном месяце (производная таблица) и примечании в другом. Я получаю различное количество строк, возвращаемых, когда я выполняю правое соединение, и когда я делаю левое соединение, но когда я складываю все премии, оно всегда равно 1323608.401 вместо 1325233.399. Я думал, что решением моей проблемы было бы использовать полное внешнее объединение и, таким образом, вернуть все результаты (даже те, которые не совпадают), так что тогда моя общая премия составила бы 1325233.399, но я все еще получаю только 1323608.401 независимо от того, какой тип объединения я пытаюсь использовать. У кого-нибудь есть идеи, что здесь может происходить ??? Любая помощь будет высоко ценится. Спасибо!

    SELECT   sept.eprem-aug.eprem as eprem , sept.coveragecode, zipcode 
from

(select 
SUM(EarnedPremium) AS eprem,coveragecode, evaluationdate, zipcode                       
FROM         dbo.StatRateSummary                            
where evaluationdate = '09-30-2011' 
and decpagetypecode != 'x'
GROUP BY evaluationdate ,coveragecode, zipcode

) as sept full outer join 

(select 
SUM(EarnedPremium) AS eprem,coveragecode, evaluationdate, zipcode                       
FROM         dbo.StatRateSummary                            
where evaluationdate = CONVERT(DATETIME, DATEADD(d,-1,DATEADD(mm, DATEDIFF(m,0,'09-30-2011'),0)), 102)  
and decpagetypecode != 'x'
GROUP BY evaluationdate ,coveragecode, zipcode

) as aug on sept.coveragecode = aug.coveragecode and sept.zipcode = aug.zipcode
where sept.coveragecode is not null and sept.coveragecode <> ''
order by coveragecode, sept.evaluationdate

Ответы [ 2 ]

1 голос
/ 23 ноября 2011

Все, что мне нужно было сделать, это изменить первую строку кода, чтобы преобразовать любое нулевое премиальное значение в 0.

SELECT   isnull(sept.eprem,0)-isnull(aug.eprem,0) as eprem , sept.coveragecode, zipcode 
from

(select 
SUM(EarnedPremium) AS eprem,coveragecode, evaluationdate, zipcode                       
FROM         dbo.StatRateSummary                            
where evaluationdate = '09-30-2011' 
and decpagetypecode != 'x'
GROUP BY evaluationdate ,coveragecode, zipcode

) as sept full outer join 

(select 
SUM(EarnedPremium) AS eprem,coveragecode, evaluationdate, zipcode                       
FROM         dbo.StatRateSummary                            
where evaluationdate = CONVERT(DATETIME, DATEADD(d,-1,DATEADD(mm, DATEDIFF(m,0,'09-30-2011'),0)), 102)  
and decpagetypecode != 'x'
GROUP BY evaluationdate ,coveragecode, zipcode

) as aug on sept.coveragecode = aug.coveragecode and sept.zipcode = aug.zipcode
where sept.coveragecode is not null and sept.coveragecode <> ''
order by coveragecode, sept.evaluationdate
0 голосов
/ 22 ноября 2011

Ваше условие FULL OUTER JOIN должно выглядеть следующим образом:

SELECT   sept.eprem-aug.eprem as eprem , sept.coveragecode, zipcode 
from

(select 
SUM(EarnedPremium) AS eprem,coveragecode, evaluationdate, zipcode                       
FROM         dbo.StatRateSummary                            
where evaluationdate = '09-30-2011' 
and decpagetypecode != 'x'
-- Migrated WHERE Condition
AND COALESCE(eprem.coveragecode, '') > ''
GROUP BY evaluationdate ,coveragecode, zipcode

) as sept FULL OUTER join 

(select 
SUM(EarnedPremium) AS eprem,coveragecode, evaluationdate, zipcode                       
FROM         dbo.StatRateSummary                            
where evaluationdate = CONVERT(DATETIME, DATEADD(d,-1,DATEADD(mm, DATEDIFF(m,0,'09-30-2011'),0)), 102)  
and decpagetypecode != 'x'
GROUP BY evaluationdate ,coveragecode, zipcode

) as aug on sept.coveragecode = aug.coveragecode and sept.zipcode = aug.zipcode
/*
|| See SEPT derived table for elimination of NULL and '' coverage codes
|| where sept.coveragecode is not null and sept.coveragecode <> ''
*/
order by coveragecode, sept.evaluationdate

Следует учитывать, что при использовании OUTER JOIN критерия WHERE может заставить оптимизатор переписать JOIN вместо INNER JOIN.

Надеюсь, это поможет.

...