查询中的 LEFT JOIN 返回比预期更多的记录
Posted
技术标签:
【中文标题】查询中的 LEFT JOIN 返回比预期更多的记录【英文标题】:LEFT JOIN in Query returning more records than desired 【发布时间】:2017-08-26 22:26:01 【问题描述】:我正在处理一个 MS ACCESS 查询,它应该从一个主表(由 FROM 指定)中提取所有可用数据,然后通过 LEFT JOIN 加入三个额外的表。我的问题是由于一对多关系,查询返回了更多记录。
有什么方法可以在主表中每行只返回一条记录?任何帮助是极大的赞赏!!谢谢!
SELECT tbl_Item_PO.Item,
tbl_ItemSKUType.SKU,
tbl_Item_PO.[EX-FACTORY DATE],
tbl_Item_PO.[QTY PER SHIPMENT],
IIf(tbl_Item_PO.Item=Posted_Inv_Tran.Item And tbl_Item_PO.Whse=Posted_Inv_Tran.Whse And tbl_Item_PO.[ITR#]=Posted_Inv_Tran.[TRN Number],0,tbl_Item_PO.[QTY PER SHIPMENT]) AS QTY,
tbl_Item_PO.WHSE, tbl_WhseRegion.Region
FROM ((tbl_Item_PO
LEFT JOIN tbl_ItemSKUType ON tbl_Item_PO.item = tbl_ItemSKUType.Item)
LEFT JOIN tbl_WhseRegion ON tbl_Item_PO.WHSE = tbl_WhseRegion.Whse)
LEFT JOIN Posted_Inv_Tran ON (tbl_Item_PO.[ITR#] = Posted_Inv_Tran.[TRN Number]) AND (tbl_Item_PO.Whse = Posted_Inv_Tran.Whse) AND (tbl_Item_PO.Item = Posted_Inv_Tran.Item);
我也尝试在只返回一条记录的连接语句中创建子查询,但我也无法让它工作:
SELECT po.Item,
ist.SKU,
po.[EX-FACTORY DATE],
po.[QTY PER SHIPMENT],
IIf(po.Item=itr.Item And po.Whse=itr.Whse And po.[ITR#]=itr.[TRN Number],0,po.[QTY PER SHIPMENT]) AS QTY,
po.WHSE,
wh.Region
FROM ((tbl_Item_PO po
LEFT JOIN (select top 1 * from tbl_ItemSKUType
RIGHT JOIN tbl_Item_PO on tbl_ItemSKUType.Item = tbl_Item_PO.item
WHERE tbl_Item_PO.Item = tbl_ItemSKUType.Item)
ist ON po.item = ist.Item)
LEFT JOIN (select top 1 * from tbl_WhseRegion
RIGHT JOIN tbl_Item_PO on tbl_WhseRegion.Whse = tbl_Item_PO.Whse
WHERE tbl_Item_PO.whse = tbl_WhseRegion.Whse)
wh ON po.Whse = wh.Whse)
LEFT JOIN (select top 1 * from Posted_Inv_Tran
RIGHT JOIN tbl_Item_PO on Posted_Inv_Tran.[TRN Number] = tbl_Item_PO.[ITR#] AND Posted_Inv_Tran.Whse = tbl_Item_PO.Whse AND Posted_Inv_Tran.Item = tbl_Item_PO.Item
WHERE (tbl_Item_PO.[ITR#] = Posted_Inv_Tran.[TRN Number]) AND (tbl_Item_PO.Whse = Posted_Inv_Tran.Whse) AND (tbl_Item_PO.Item = Posted_Inv_Tran.Item))
it ON (po.[ITR#] = it.[TRN Number]) AND (po.Whse = it.Whse) AND (po.Item = it.Item);
【问题讨论】:
你可能不想要一个三左连接,你可能想要两个左连接的内连接。 Because 你并不总是在最左边的表的键上加入等于它的 FK。想一想:左连接返回内连接返回的内容以及由空值扩展的不匹配行。非 FK 键的内连接可以引入多行。但是在我回答之前,您需要给出限制条件和最好的示例数据来确认。事实上,代码总是给一个minimal reproducible example 或者一个问题是题外话。 【参考方案1】:您可以使用group by
子句来实现。确保列出该子句中标识一行的所有字段,并且您在 select
子句中拥有的所有其他表达式/字段都使用某些聚合函数进行聚合,例如 Min()
。
注意:您的IIf
条件不需要检查所有这些字段,只需一个就足够了:当一个匹配时,所有将匹配:
SELECT tbl_Item_PO.Item,
Min(tbl_ItemSKUType.SKU) AS SKU,
tbl_Item_PO.[EX-FACTORY DATE],
tbl_Item_PO.[QTY PER SHIPMENT],
Min(IIf(tbl_Item_PO.Item=Posted_Inv_Tran.Item, 0,
tbl_Item_PO.[QTY PER SHIPMENT])) AS QTY,
tbl_Item_PO.WHSE,
Min(tbl_WhseRegion.Region) AS Region
FROM ((tbl_Item_PO
LEFT JOIN tbl_ItemSKUType
ON tbl_Item_PO.item = tbl_ItemSKUType.Item)
LEFT JOIN tbl_WhseRegion
ON tbl_Item_PO.WHSE = tbl_WhseRegion.Whse)
LEFT JOIN Posted_Inv_Tran
ON (tbl_Item_PO.[ITR#] = Posted_Inv_Tran.[TRN Number])
AND (tbl_Item_PO.Whse = Posted_Inv_Tran.Whse)
AND (tbl_Item_PO.Item = Posted_Inv_Tran.Item)
GROUP BY tbl_Item_PO.Item,
tbl_Item_PO.[EX-FACTORY DATE],
tbl_Item_PO.[QTY PER SHIPMENT],
tbl_Item_PO.WHSE;
【讨论】:
谢谢!这可能有效。我唯一担心的是,对于连接表中具有多个匹配项的记录,QTY(数量)值会被放大。 MIN 函数会解决这个问题吗?Min
将只取一个值,即适合连接的众多值中的最小一个。但是由于当您有多个连接匹配时,该值实际上将是相同的重复值,这仅意味着:“选择该值”。如果您使用Sum
而不是Min
,它会炸毁。以上是关于查询中的 LEFT JOIN 返回比预期更多的记录的主要内容,如果未能解决你的问题,请参考以下文章
SQL语句中LEFT JOIN和RIGHT JOIN 以及INNER JOIN的区别
多表查询-inner join left join right joinfull join