当表FI_CurrentReceiptData只有2行时,我有以下查询返回4个结果。额外的行是完全重复的。我可以使用DISTINCT
来修复,但我的理解是这是不好的做法,我会更好地找到并纠正错误(这是正确的吗?)。
为什么此查询会将结果加倍?
所有变量都在存储过程的其他地方声明,并且此查询会返回所需的字段。
SELECT ( (Select Max(ReceiptNumber)
from Avanti_InventoryReceipts) + CR.Seq ),
CR.ItemNumber,
Convert(char(8), GETDATE(), 112),
PONum,
'FL-INV',
PH.POVendor,
0,
0,
'O',
CR.QtyOrdered,
QtyReceivedToday,
QtyReceivedToday,
Case @closePO
When 'N' Then Case
When ( QtyOrdered - QtyReceivedToday ) < 0 Then 0
Else ( QtyOrdered - QtyReceivedToday )
End
When 'Y' Then 0
Else 0
End,
PD.TransCost * QtyReceivedToday,
IH.PriceWholeSale,
IH.CostLast,
QtyReceivedToday,
0,
'',
PODetailDescription /* , .... More columns...*/
FROM FI_CurrentReceiptData CR
LEFT JOIN Avanti_PODetails PD
ON CR.PONum = PD.PONumber
LEFT JOIN Avanti_POHeader PH
ON CR.PONum = PH.PONumber
LEFT JOIN Avanti_InventoryHeader IH
ON CR.ItemNumber = IH.ItemNumber
NEW WHERE CLERE解决方案:
FROM FI_CurrentReceiptData CR
inner JOIN Avanti_PODetails PD ON CR.PONum = PD.PONumber AND CR.ItemNumber = PD.TransItem AND CR.QtyOrdered = PD.TransQty
left JOIN Avanti_POHeader PH ON PD.PONumber = PH.PONumber
left JOIN Avanti_InventoryHeader IH ON CR.ItemNumber = IH.ItemNumber
答案 0 :(得分:3)
通常当你将左连接字符串组合在一起时,你必须继续加入'左'表 - 这不是一个规则,而是它的良好做法,所以你不要错过连接。在您的左连接字符串中,它包含4个表,您只将第一个连接到所有三个表:
FROM FI_CurrentReceiptData CR
LEFT JOIN Avanti_PODetails PD
ON CR.PONum = PD.PONumber
LEFT JOIN Avanti_POHeader PH
ON CR.PONum = PH.PONumber
LEFT JOIN Avanti_InventoryHeader IH
ON CR.ItemNumber = IH.ItemNumber
你没有将PD加入IH到PH,但基本上是将CR表连接到所有三个 - 所以基本上它是在PD和PH和IH之间进行交叉连接(基于它们匹配的任何字段)。我假设POheader和POdetails有一些匹配的字段....我假设它们之间的一对多关系? (根据名称)。所以那里需要有一些限制......
编辑:
你可以尝试,(根据田野关系)
FROM FI_CurrentReceiptData CR
LEFT JOIN Avanti_PODetails PD
ON CR.PONum = PD.PONumber
LEFT JOIN Avanti_POHeader PH
ON CR.PONum = PH.PONumber AND PD.PONumber = PH.PONumber
LEFT JOIN Avanti_InventoryHeader IH
ON CR.ItemNumber = IH.ItemNumber
编辑2:
好的,所以你说的是,CR有2行,CR与PH有一对一的关系,PH与PD的关系是1对多。 CR也与IH有一对一的关系。在这种情况下,假设您具有参考完整性,您可以将您的联接更改为:
FROM FI_CurrentReceiptData CR
LEFT JOIN Avanti_POHeader PH ON CR.PONum = PD.PONumber
INNER JOIN Avanti_PODetails PD ON PH.PONumber = PD.PONUmber
LEFT JOIN Avanti_InventoryHeader IH ON CR.ItemNumber = IH.ItemNumber
让我们退后一步 - 这将根据它们是否匹配来限制PD和PH行,并且即使它们不匹配也不会得到空值(这是左连接所做的)。
但是现在,如果CR中有2行,并且每个PONumbers在POHeader中有2行,并且每个POheader在POdetails中有超过1行,那么你肯定会有重复。真的没有办法避免这种情况。原因是:
CR TABLE
PONum ItemNumber
--------- ----------
123 ABC
456 DEF
PH TABLE
PONumber
---------
123
456
PD TABLE
PONumber ItemNumber
--------- -----------
123 ABC
123 ABC1
456 DEF
456 DEF1
...如果您将CR表连接到PH表,您将只获得两行。如果您将PH加入PD表,那么您将有4行。如果你加入所有3,那么你也将获得4行。连接的性质遍及所有表,因此当您从CR表转到PH时,它会获得2行的结果集...然后该结果集将连接到PD,并且有4行。如果您可以确认您的数据是这样的,那么您获得的结果集是正确的。
答案 1 :(得分:1)
由于您正在进行LEFT JOINS,因此所有匹配记录都会返回1行。因此,您加入的其中一个表格返回的行数超过1行。
尝试临时更改查询以将其他表主键添加到列列表中,您应该能够快速判断哪个表返回的行超过1行。
答案 2 :(得分:0)
其中一个连接表有多个匹配行。 我无法确定哪一个,但如果我是你,我会开始寻找 在Avanti_PODetails表中。它对两个收据中的任何一个都有多个匹配记录吗?