Чому ця Повна зовнішня приєднання не працює?


10

Раніше я використовував Full Outer Joins, щоб отримати бажані результати, але, можливо, я не повністю розумію цю концепцію, оскільки я не в змозі досягти того, що має бути простим приєднанням.

У мене є 2 таблиці (які я називаю t1 і t2) з 2 полями кожна:

t1

Policy_Number Premium
101             15
102              7
103             10
108             25
111              3

t2

Policy_Number   Loss
101              5
103              9
107              20

Що я намагаюся зробити - це отримати суму премій та суму втрат з обох таблиць, а також Policy_Number. Я використовую код:

select sum(premium) Prem_Sum, sum(Loss) Loss_Sum, t1.policynumber
from t1 full outer join t2 on t1.policynumber = t2.policynumber
group by t1.policynumber

Вищевказаний код поверне правильну підсумкову суму, але він згрупує всі записи, де не відповідає збіга_політика під "NULL" policy_number.

Я хотів би, щоб мій результат виглядав таким чином

Policy_Number    Prem_Sum    Loss_Sum
    107            NULL        20
    111              3        NULL
    101             15          5

тощо ...

Я не хочу, щоб результат показував NULL policy_number, як показано нижче (оскільки немає такого поняття, як NULL policy_number. Це просто загальна сума, коли policy_number з обох таблиць не збігається):

Policy_Number    Prem_Sum   Loss_Sum
   NULL            35         NULL

Якщо я виберу і групую по t2.policy_number замість t1.policy_number, я отримаю щось на зразок нижче як запис.

Policy_Number    Prem_Sum   Loss_Sum
   NULL            NULL         20

Знову ж таки, я не проти бачити NULL під Prem_Sum або під Loss_sum, але я не хочу NULL під Policy_Number. Я хотів би, щоб мої результати були чимось подібними

Policy_Number    Prem_Sum    Loss_Sum
    107            NULL        20
    111              3        NULL
    101             15          5

ест .....

Я думав, що повне зовнішнє з'єднання це здійснить, але я думаю, що мені щось не вистачає. Я думав, може, я міг би вибрати та об'єднати групи t1.policy_number та t2.policy_number як підзапит, а потім, можливо, зробити CASE у зовнішньому запиті чи щось таке ??? Я не думаю, що це повинно бути таким складним.

Якісь ідеї чи поради?

Відповіді:


8

Ви повинні зробити прокрутку на обох номерах полісів, щоб ви могли правильно групуватися.

Оскільки це зовнішнє з'єднання, існує можливість, щоб одна сторона з'єднання була NULL, зберігаючи дані.

select sum(premium) Prem_Sum, sum(Loss) Loss_Sum, isnull(t1.policynumber, t2.policynumber)
from t1 full outer join t2 on t1.policynumber = t2.policynumber
group by isnull(t1.policynumber, t2.policynumber)

... це означає, що нулі обробляються як значення SQL, тому вам потрібен ISNULL (). Ось чому SQL так погано рот. Але я все ще користуюся ним щодня.
Пол-Себастьян Маноле

4

Повне зовнішнє з'єднання створить потрібну вам структуру записів, але це не додасть номер політики 107 у таблицю 1 для вас.

Я думаю, що те, що тобі потрібно, - це щось, що відповідає

select coalesce(t1.policy_number, t2.policy_number) as PolicyNumber, 
sum(t1.premium) as PremSum, sum(t2.loss) as LossSum
from t1 full outer join t2 on t1.policy_number = t2.policy_number
group by coalesce(t1.policy_number, t2.policy_number)

2

Щоб надати трохи більше інформації, чому ваш конкретний запит не працював. Ваш початковий код:

select sum(premium) Prem_Sum, sum(Loss) Loss_Sum, t1.policynumber 
from t1 full outer join t2 on t1.policynumber = t2.policynumber 
group by t1.policynumber 

На перший погляд це виглядає так, як це має спрацювати. Однак зауважте, що вказаний третій стовпець - t1.policynumber. Це також єдиний стовпець групування. Через це SQL Server бачить лише значення в t1, залишаючи будь-які значення не в t1 як нульові (адже, пам’ятайте, це повне зовнішнє з'єднання). Код isnull (t1.policynumber, t2.policynumber) надасть вам усі ненульові значення в t1, а потім використовувати значення в t2.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.