这个简单的查询存在问题。我收到错误
“子查询返回的值超过1。当子查询遵循=,!=,<,<=,>,> =或将子查询用作表达式时,不允许这样做。”
SELECT TOP 100 PERCENT
dbo.Inventory.PARTNO
,( SELECT ISNULL(SUM(dbo.PurchaseOrderReceived.QtyReceived), 0)
FROM dbo.PurchaseOrderReceived
JOIN dbo.PurchaseOrderlineItems
ON dbo.PurchaseOrderReceived.POLIID = dbo.PurchaseOrderlineItems.POLIID
JOIN dbo.Inventory
ON dbo.PurchaseOrderlineItems.InvMasID = dbo.Inventory.InvMasID
JOIN dbo.Duties Duties_1 ON dbo.Inventory.DutyClass = Duties_1.DutyID
WHERE (Duties_1.DutyClass = 252)
AND (dbo.PurchaseOrderlineItems.Deleted = 0)
AND (dbo.PurchaseOrderReceived.ReceivedDate > CONVERT(DATETIME, '2018-08-22 00:00:00', 102))
GROUP BY dbo.Inventory.PARTNO
) AS Purchased
,ISNULL(SUM(dbo.OrderItems.QtyShipped), 0) AS Ordered
,ISNULL(SUM(DISTINCT dbo.MRP.QtyOnHand), 0) AS QOH
FROM dbo.Orders
JOIN dbo.OrderItems
JOIN dbo.Inventory
ON dbo.OrderItems.InvMasID = dbo.Inventory.InvMasID
ON dbo.Orders.OrderID = dbo.OrderItems.OrderID
JOIN dbo.MRP ON dbo.Inventory.InvMasID = dbo.MRP.InvMasID
JOIN dbo.Duties ON dbo.Inventory.DutyClass = dbo.Duties.DutyID
WHERE (dbo.Orders.ShipDate > CONVERT(DATETIME, '2018-08-22 00:00:00', 102))
AND (dbo.Duties.DutyClass = 252)
GROUP BY dbo.Inventory.PARTNO
我已经尝试解决此问题,并且知道我缺少一个简单的解决方案。与主查询分开时,子查询本身会检索我要查找的信息。谢谢你的帮助!
答案 0 :(得分:1)
我只能在上面的查询中看到此子查询
SELECT ISNULL(SUM(dbo.PurchaseOrderReceived.QtyReceived),0)
FROM dbo.PurchaseOrderReceived
INNER JOIN dbo.PurchaseOrderlineItems ON dbo.PurchaseOrderReceived.POLIID = dbo.PurchaseOrderlineItems.POLIID
INNER JOIN dbo.Inventory ON dbo.PurchaseOrderlineItems.InvMasID = dbo.Inventory.InvMasID
INNER JOIN dbo.Duties Duties_1 ON dbo.Inventory.DutyClass = Duties_1.DutyID
WHERE (Duties_1.DutyClass = 252)
AND (dbo.PurchaseOrderlineItems.Deleted = 0)
AND (dbo.PurchaseOrderReceived.ReceivedDate > CONVERT(DATETIME,'2018-08-22 00:00:00',102))
GROUP BY dbo.Inventory.PARTNO
按PARTNO分组,应该返回多个值。确保不超过一个满足您where
和inner join
条件的条件的零件编号
答案 1 :(得分:1)
子查询需要返回一个值,而在您的子查询中,它返回了多个值,这是因为PARTNO
内部的组。您可以删除该组,或者使用TOP 1,或者仅包含带有SUM,MAX,MIN的子查询来解决该问题。
另一件事,由于子查询也使用相同和相对的源,因此您可以将它们连接起来(这会更好)。
类似的东西:
SELECT TOP 100 PERCENT
dbo.Inventory.PARTNO
, ISNULL(SUM(dbo.por.QtyReceived), 0) AS Purchased
, ISNULL(SUM(dbo.OrderItems.QtyShipped), 0) AS Ordered
, ISNULL(SUM(DISTINCT dbo.MRP.QtyOnHand), 0) AS QOH
FROM dbo.Orders
JOIN dbo.OrderItems ON dbo.Orders.OrderID = dbo.OrderItems.OrderID
JOIN dbo.Inventory ON dbo.OrderItems.InvMasID = dbo.Inventory.InvMasID
JOIN dbo.MRP ON dbo.Inventory.InvMasID = dbo.MRP.InvMasID
JOIN dbo.Duties ON dbo.Inventory.DutyClass = dbo.Duties.DutyID
LEFT JOIN dbo.PurchaseOrderlineItems poli ON poli.InvMasID = dbo.Inventory.InvMasID AND poli.Deleted = 0
LEFT JOIN dbo.PurchaseOrderReceived por ON por.POLIID = poli.POLIID AND (dbo.por.ReceivedDate > CONVERT(DATETIME, '2018-08-22 00:00:00', 102))
WHERE
dbo.Orders.ShipDate > CONVERT(DATETIME, '2018-08-22 00:00:00', 102)
AND (dbo.Duties.DutyClass = 252)
GROUP BY dbo.Inventory.PARTNO
由于您没有提供任何样本,因此我无法验证结果,但我认为足以证明这种方法。
答案 2 :(得分:1)
简单的解决方案似乎是在子查询或主SELECT语句中为清单表取别名,并通过主查询中的PARTNO
过滤子查询中的记录。我认为反正还是一个好主意:
SELECT TOP 100 PERCENT
i.PARTNO
, ( SELECT ISNULL(SUM(por.QtyReceived), 0)
FROM dbo.PurchaseOrderReceived por
JOIN dbo.PurchaseOrderlineItems poli ON por.POLIID = poli.POLIID
JOIN dbo.Inventory i1 ON poli.InvMasID = i1.InvMasID
JOIN dbo.Duties d1 ON i1.DutyClass = d1.DutyID
WHERE (d1.DutyClass = 252)
AND (i1.PARTNO = i.PARTNO)
AND (poli.Deleted = 0)
AND (por.ReceivedDate > CONVERT(DATETIME, '2018-08-22 00:00:00', 102))
) AS Purchased
, ISNULL(SUM(oi.QtyShipped), 0) AS Ordered
, ISNULL(SUM(DISTINCT m.QtyOnHand), 0) AS QOH
FROM dbo.Orders o
JOIN dbo.OrderItems oi ON o.OrderID = oi.OrderID
JOIN dbo.Inventory i ON oi.InvMasID = i.InvMasID
JOIN dbo.MRP m ON i.InvMasID = m.InvMasID
JOIN dbo.Duties d ON i.DutyClass = d.DutyID
WHERE (o.ShipDate > CONVERT(DATETIME, '2018-08-22 00:00:00', 102))
AND (d.DutyClass = 252)
GROUP BY i.PARTNO
答案 3 :(得分:1)
该重新开始并应用一些最佳编码实践了。您的加入是一种“非典型”方式,许多人都难以理解。混淆的代码很可能导致错误。移动您的联接子句以遵循实际的联接表。例如,您有
FROM dbo.Orders
JOIN dbo.OrderItems
JOIN dbo.Inventory
ON dbo.OrderItems.InvMasID = dbo.Inventory.InvMasID
ON dbo.Orders.OrderID = dbo.OrderItems.OrderID
JOIN dbo.MRP ON dbo.Inventory.InvMasID = dbo.MRP.InvMasID
JOIN dbo.Duties ON dbo.Inventory.DutyClass = dbo.Duties.DutyID
您没有通过关联的ON子句第一次跟随OrderItems进行联接-在连接到Inventory之后,它以某种方式结束。奇怪的是,加入MRP的on子句确实紧随该表之后。不一致是不良的开发人员习惯。 IMO比“非典型”地做事更糟。最后,使用别名来减少混乱并使代码更易于阅读。易于阅读意味着您的代码更容易被理解。改进的版本是:
FROM dbo.Orders as Ord
JOIN dbo.OrderItems as Itm on Ord.OrderID = Itm.OrderID
JOIN dbo.Inventory as Inv on Itm.InvMasID = Inv.InvMasID
JOIN dbo.MRP as MRP ON Inv.InvMasID = MRP.InvMasID
JOIN dbo.Duties as Duties ON Inv.DutyClass = Duties.DutyID
您最好对表进行模式限定-很少看到张贴者这样做。但是,这也会使名称变得很长,这是建议使用别名的原因之一。
接下来,您有“选择前100%” 。每当您认为需要此功能时,请停止编写代码,然后再做其他事情。 从不有用。如果SSMS试图通过添加来“修复”某些东西,请不要相信。
您要发布的问题是子查询。您试图“解决”原始问题,但没有告诉我们该问题是什么。这是查询返回了错误的求和值。为什么这样做呢?因为您没有将子查询与外部查询相关联,所以它为每个库存清单行计算了一个值。
为此,您需要在子查询中删除对库存的联接。为什么?因为适当的库存行的关键字将来自外部查询-这就是将内部与外部相关联的方式。将没有group by子句,因为您的目标是为外部查询中的每一行计算一个值。从逻辑上讲,group by子句表明您打算在该查询中产生多行-这不是您想要发生的(并且不会发生,因为引擎将在这种情况下产生错误-您已发现)。其他一些问题:
因此,应用所有这些更改应该会留下类似的内容:
,( SELECT SUM(POR.QtyReceived)
FROM dbo.PurchaseOrderReceived as POR
JOIN dbo.PurchaseOrderlineItems as POItm
ON POR.POLIID = POItm.POLIID
WHERE Inv.InvMasID = POItm.InvMasID --this is the correlation
AND POItm.Deleted = 0
AND POR.ReceivedDate > CONVERT(DATETIME, '2018-08-22 00:00:00', 102))
) AS Purchased
希望我没有添加任何错别字或错误-很明显我自己无法检查此问题。但这至少可以为您提供一个更好的起点。您对日期的使用似乎令人怀疑,但是-再次-我不知道您的架构或数据,其使用方式或您要查询的内容。
答案 4 :(得分:0)
输入此条件,并且dbo.Orders.PARTNO = dbo.Inventory.PARTNO 和前1名
SELECT TOP 100 PERCENT
dbo.Inventory.PARTNO
,( SELECT Top 1 ISNULL(SUM(dbo.PurchaseOrderReceived.QtyReceived), 0)
FROM dbo.PurchaseOr,derReceived
JOIN dbo.PurchaseOrderlineItems
ON dbo.PurchaseOrderReceived.POLIID = dbo.PurchaseOrderlineItems.POLIID
JOIN dbo.Inventory
ON dbo.PurchaseOrderlineItems.InvMasID = dbo.Inventory.InvMasID
JOIN dbo.Duties Duties_1 ON dbo.Inventory.DutyClass = Duties_1.DutyID
WHERE (Duties_1.DutyClass = 252)
AND (dbo.PurchaseOrderlineItems.Deleted = 0)
AND (dbo.PurchaseOrderReceived.ReceivedDate > CONVERT(DATETIME, '2018-08-22 00:00:00', 102))
AND dbo.Orders.PARTNO = dbo.Inventory.PARTNO
GROUP BY dbo.Inventory.PARTNO
) AS Purchased
,ISNULL(SUM(dbo.OrderItems.QtyShipped), 0) AS Ordered
,ISNULL(SUM(DISTINCT dbo.MRP.QtyOnHand), 0) AS QOH
FROM dbo.Orders
JOIN dbo.OrderItems
JOIN dbo.Inventory
ON dbo.OrderItems.InvMasID = dbo.Inventory.InvMasID
ON dbo.Orders.OrderID = dbo.OrderItems.OrderID
JOIN dbo.MRP ON dbo.Inventory.InvMasID = dbo.MRP.InvMasID
JOIN dbo.Duties ON dbo.Inventory.DutyClass = dbo.Duties.DutyID
WHERE (dbo.Orders.ShipDate > CONVERT(DATETIME, '2018-08-22 00:00:00', 102))
AND (dbo.Duties.DutyClass = 252)
GROUP BY dbo.Inventory.PARTNO