需要帮助了解此 TSQL 连接行为
Need help understanding this TSQL join behavior
我只是不知道如何 google 我的问题,所以如果这个问题已经有了答案,我深表歉意。我的查询正常运行,但在进行故障排除时,我遇到了我不理解的行为。
我有三个 table 具有完全相同的结构——一个用于已被解雇的员工,一个用于选择放弃医疗保险的员工,一个用于没有医疗保险的员工.这个数据有多个公司,我是按公司和部门分组的。
我正在做 FULL OUTER JOIN,因为一些 company/division 组可能有 0 个终止雇员,但可能有一些豁免雇员(例如)。
三个来源table的结构是:
公司---部门---NumbOfEmployees
目标视图的结构是:
公司---部门---NumbOfTermEmp---NumbOfWaiverEmp---NumbOfNonMedEmp
所以我基本上是在拉平数据。
如果我将 table 1 连接到 table 2,然后将 table 2 连接到 table 3,我会得到我期望的数据。
如果我加入 table 1 到 table 2,然后 table 1 加入 table 3,我不会。我会得到一个额外的行,例如,table 1 中不存在数据,但 table 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
s 可能很难处理,尤其是对于多个表,因为连接键可能与早期的连接不匹配。我的偏好是列出所有公司和部门,然后使用 left join
代替。或者,上述查询使用 union all
和 group by
.
我可以立即想到至少一种会导致这种情况的情况。
进行 "Bad" 连接(T2 和 T3 都连接到 T1),假设您有一行存在于 T2 和 T3 中,但不存在于 T1 中。
那么你基本上是这样做的:
First Join
T1 T2
NULL Data
Second Join
T1 T3
NULL Data
并且由于您没有在任何地方将 T2 连接到 T3,因此它在两列中都看不到 "Data" 的连接,因此它创建了两行。第一次加入一个,第二次加入一个。
要真正扁平化数据,您应该在与 T3 的连接条件中包含 T2 和 T3 之间的关系(T3 连接到 T1 和 T2)。
至少,我 认为 这会起作用,两个连接都是 FULL OUTER。
我只是不知道如何 google 我的问题,所以如果这个问题已经有了答案,我深表歉意。我的查询正常运行,但在进行故障排除时,我遇到了我不理解的行为。
我有三个 table 具有完全相同的结构——一个用于已被解雇的员工,一个用于选择放弃医疗保险的员工,一个用于没有医疗保险的员工.这个数据有多个公司,我是按公司和部门分组的。
我正在做 FULL OUTER JOIN,因为一些 company/division 组可能有 0 个终止雇员,但可能有一些豁免雇员(例如)。
三个来源table的结构是: 公司---部门---NumbOfEmployees
目标视图的结构是:
公司---部门---NumbOfTermEmp---NumbOfWaiverEmp---NumbOfNonMedEmp
所以我基本上是在拉平数据。
如果我将 table 1 连接到 table 2,然后将 table 2 连接到 table 3,我会得到我期望的数据。
如果我加入 table 1 到 table 2,然后 table 1 加入 table 3,我不会。我会得到一个额外的行,例如,table 1 中不存在数据,但 table 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
s 可能很难处理,尤其是对于多个表,因为连接键可能与早期的连接不匹配。我的偏好是列出所有公司和部门,然后使用 left join
代替。或者,上述查询使用 union all
和 group by
.
我可以立即想到至少一种会导致这种情况的情况。
进行 "Bad" 连接(T2 和 T3 都连接到 T1),假设您有一行存在于 T2 和 T3 中,但不存在于 T1 中。
那么你基本上是这样做的:
First Join
T1 T2
NULL Data
Second Join
T1 T3
NULL Data
并且由于您没有在任何地方将 T2 连接到 T3,因此它在两列中都看不到 "Data" 的连接,因此它创建了两行。第一次加入一个,第二次加入一个。
要真正扁平化数据,您应该在与 T3 的连接条件中包含 T2 和 T3 之间的关系(T3 连接到 T1 和 T2)。
至少,我 认为 这会起作用,两个连接都是 FULL OUTER。