为什么此完全外部联接不起作用?


10

我之前曾使用“完全外部联接”来获得所需的结果,但也许我不完全理解该概念,因为我无法完成应该是简单联接的工作。

我有2个表(分别称为t1和t2),每个表有2个字段:

11

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

上面的代码将返回正确的总和,但会将“ policy_number”下“ 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

同样,我不介意在Prem_Sum或Loss_sum下看到NULL,但我不希望在Policy_Number下看到NULL。我希望我的结果像

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

等等.....

我以为完全外部联接可以完成此任务,但我想我缺少了一些东西。我在想也许我可以选择t1.policy_number和t2.policy_number作为子查询并进行分组,然后在外部查询中执行CASE或其他操作?我不认为应该这么复杂。

有什么想法或建议吗?

Answers:


8

您应该对两个策略编号都进行一次isull操作,以便可以正确分组。

由于它是外部联接,因此联接的一侧可能仍然为数据,而为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中没有的任何值都保留为空(因为请记住,这是一个完整的外部联接)。notull(t1.policynumber,t2.policynumber)代码将为您提供t1中的所有非空值,然后在t2中使用值。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.