2

我需要加入至少 4 张桌子。表 A 是一个关联表,其中包含表 B 和 C 的 guid、Parentguid (B)、Childguid (C)。表 D 仅包含表 C 的信息。

我需要结果看起来像这样。

B - C - D

监视器 - 计算机名称 - 活动

所以主要是显示所有的B表,只有连接到B的C表,只有与C关联的D表。

我怀疑我需要子连接()。我仍然是一个新手,这在我的脑海中是有道理的,但我似乎无法使代码工作。在过去的 2 天里,我一直在玩 joins。

FROM vHWDesktopMonitor mon             -- [Symantec_CMDB2].[dbo].[ResourceAssociation]
join ResourceAssociation RM on mon._ResourceGuid = RM.ParentResourceGuid 
full outer join vComputer comp on RM.ChildResourceGuid = comp.Guid 
full outer join vAsset on RM.ChildResourceGuid = vAsset._ResourceGuid 
4

2 回答 2

2
FROM vHWDesktopMonitor A
FULL OUTER JOIN ResourceAssociation B
  on A._ResourceGuid = B.ParentResourceGuid 
LEFT JOIN vComputer C
  on B.ChildResourceGuid = C.Guid 
LEFT JOIN vAsset D
  on C.ChildResourceGuid = D._ResourceGuid 

所以上面会返回

  • 来自 A 的所有记录和来自 B 的所有记录(A、B 之间的完整外部)
  • 仅来自 C 且位于 B 中的记录(左侧在 B 和 C 之间)
  • 仅来自 D 且位于 C 中的记录(左侧在 C 和 D 之间)

但是,如果您应用任何 where 子句限制,它可能会减少由于左连接或外连接而保留的记录......

例如,如果 A._ResourceGuid ='7' 存在于 A 但不在 B 中;并且您设置 where B._ResourceGuid ='7' 然后将保留 A 记录,因为完整的外部联接将被排除(使完整的外部联接与内部联接相同)!

一个完整的外部将返回如下数据:

A B
7 7
2
  3

如果你添加一个 where 子句 where B=7 那么你可能期望得到因为完整的外部,因为你说从两者中返回所有记录... AB 7 7 2

但你最终会得到

A B
7 7

因为 where 子句出现在完整的外部之后,因此减少了 A.2 记录。为了弥补这一点,您要么必须在完整的外部执行之前对连接进行限制,要么在 where 子句中处理它(但这种方法非常混乱,容易出现错误和性能问题)

因此,当使用外连接时,您必须将限制标准放在 JOIN 本身上,如下所示。

FROM vHWDesktopMonitor A
FULL OUTER JOIN ResourceAssociation B
  on A._ResourceGuid = B.ParentResourceGuid 
 and B._resourceGuid = '7'
LEFT JOIN vComputer C
  on B.ChildResourceGuid = C.Guid 
LEFT JOIN vAsset D
  on C.ChildResourceGuid = D._ResourceGuid 

您也可以将它放在 where 子句中,但您必须记住要考虑表上的所有外部连接并为另一个包含空值(这只是混乱和缓慢)

FROM vHWDesktopMonitor A
FULL OUTER JOIN ResourceAssociation B
  on A._ResourceGuid = B.ParentResourceGuid 
LEFT JOIN vComputer C
  on B.ChildResourceGuid = C.Guid 
LEFT JOIN vAsset D
  on C.ChildResourceGuid = D._ResourceGuid 
WHERE (A._ResourceGuid is null OR B.ParentResourceGuid ='7')
于 2014-10-10T18:07:40.010 回答
0

如果我对您的理解正确,其中任何一个都应该有效”

FROM vHWDesktopMonitor mon             -- [Symantec_CMDB2].[dbo].[ResourceAssociation]
left join ResourceAssociation RM on mon._ResourceGuid = RM.ParentResourceGuid 
left join vComputer comp on RM.ChildResourceGuid = comp.Guid 
left join vAsset on comp.Guid  = vAsset._ResourceGuid 

或者

FROM vHWDesktopMonitor mon             -- [Symantec_CMDB2].[dbo].[ResourceAssociation]
left join ResourceAssociation RM on mon._ResourceGuid = RM.ParentResourceGuid 
left join (select [list fields here] from vComputer comp 
join vAsset on comp.Guid  = vAsset._ResourceGuid) comp2
on RM.ChildResourceGuid = comp2.Guid  

这应该让您获得来自 vHWDesktopMonitor 的所有记录和来自 ResourceAssociation 的相关记录,其中 vHWDesktopMonitor 中的任何记录都为空,但 ResourceAssociation 中的任何记录都没有。然后,您会在 vComputer 中获得所有记录,这些记录也在 ResourceAssociation 中。最后,您会在 vAsset 中获得 vComputer 中的所有记录。当您获取第一个表中的所有记录时,如果您没有关联的记录,则其他表中的文件将为空值。

如果这不起作用,也许您需要向我们展示一些示例数据和预期结果。

于 2014-10-10T18:05:06.463 回答