需要帮助了解此TSQL连接行为

时间:2016-03-04 19:43:10

标签: sql sql-server tsql join outer-join

我只是不知道如何谷歌搜索我的问题,所以我很抱歉,如果这个问题已经有答案了。我的查询有效,但在进行故障排除时,我遇到了一些我不理解的行为。

我有三张结构完全相同的表 - 一张是已经终止的员工,一张是选择放弃医疗保险的员工,另一张是没有医疗保险的员工。这些数据中有多家公司,我按公司和部门分组。

我正在进行全额联合,因为一些公司/部门团队可能有0名被解雇的员工,但可能有一些豁免员工(例如)。

三个源表的结构是: 公司--- ---司NumbOfEmployees

目标视图的结构是:

公司--- ---司--- NumbOfTermEmp --- NumbOfWaiverEmp NumbOfNonMedEmp

所以我基本上把数据弄平了。

如果我将表1连接到表2,然后将表2连接到表3,我会得到我期望的数据。

如果我将表1连接到表2,然后将表1连接到表3,我不会。我会得到一个额外的行,例如,表1中没有数据,但它在表2中。

下面的视觉表示:

enter image description here

我不明白幕后发生的事情足以弄清楚这种行为。这是为什么?

2 个答案:

答案 0 :(得分:2)

如果通过展平数据,您的意思是每个员工一行使用其他表中的信息,那么full outer join是一种可能性。另一个是union all聚合:

select NumbOfEmployees,
       sum(NumTerminated) as NumTerminated,
       sum(NumWaiver) as NumWaiver,
       sum(NumNonMed) as NumNonMed
from ((select Company, Division,
              NumbOfEmployees as NumTerminated, 0 as NumWaiver, 0 as NumNonMed
       from terminations
      ) union all
      (select Company, Division,
              0 as NumTerminated, NumbOfEmployees as NumWaiver, 0 as NumNonMed
       from waivers
      ) union all
      (select Company, Division,
              0 as NumTerminated, 0 as NumWaiver, NumbOfEmployees as NumNonMed
       from waivers
      )
     ) cd
group by Company, Division;

Full outer join可能难以使用,尤其是对于多个表,因为连接键可能与早期连接不匹配。我倾向于列出所有公司和部门,然后使用left join代替。或者,上述查询使用union allgroup by

答案 1 :(得分:2)

我可以立即想到至少会导致这种情况的一种情况。

执行“错误”连接(T2和T3连接到T1),假设T2和T3中存在一行,但不存在T1。

然后你基本上是这样做的:

First Join
T1    T2    
NULL  Data

Second Join
T1    T3
NULL  Data

由于你没有将T2连接到T3,因此它没有在两列中看到“数据”的连接,因此它创建了两行。一个用于第一个连接,一个用于第二个连接。

要真正扁平化数据,您应该在T2和&之间加入关系。在您的连接条件T3到T3(T3连接到T1和T2)。

至少,我认为会起作用,两个连接都是完全外的。