Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 选择子查询分组依据_Sql_Sql Server_Subquery - Fatal编程技术网

Sql 选择子查询分组依据

Sql 选择子查询分组依据,sql,sql-server,subquery,Sql,Sql Server,Subquery,我对这个简单的查询有疑问。我得到了错误 子查询返回了多个值。当子查询后跟=、!=、=或子查询用作表达式时,这是不允许的 我尝试过解决这个问题,并且知道我缺少一个简单的解决方案。子查询本身检索我正在查找的信息,与主查询一样,在分离时也是如此。谢谢你的帮助 我只能在上面的查询中看到这个子查询 SELECT ISNULL(SUM(dbo.PurchaseOrderReceived.QtyReceived),0) FROM dbo.PurchaseOrderReceived INNE

我对这个简单的查询有疑问。我得到了错误

子查询返回了多个值。当子查询后跟=、!=、=或子查询用作表达式时,这是不允许的


我尝试过解决这个问题,并且知道我缺少一个简单的解决方案。子查询本身检索我正在查找的信息,与主查询一样,在分离时也是如此。谢谢你的帮助

我只能在上面的查询中看到这个子查询

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
内部联接
条件的零件号不超过一个

我只能在上面的查询中看到此子查询

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
internal join
条件的零件号不超过一个

子查询需要返回一个值,而在您的子查询中它返回多个值,这是因为内部分组由
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

我无法验证结果,因为您没有提供任何样本,但我认为它足以展示这种方法

子查询需要返回一个值,而在您的查询中,它返回多个值,这是因为内部组by
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

我无法验证结果,因为您没有提供任何样本,但我认为它足以展示这种方法

简单的解决方案似乎是在子查询或主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

简单的解决方案似乎是在子查询或主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

是时候重新开始并应用一些最佳编码实践了。你的加入是以一种“非典型”的方式组织的,很多人都很难理解。混淆的代码可能会导致错误。移动联接子句以跟随实际联接的表。例如,你有

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
您没有在第一次加入OrderItems之后加入associated ON子句-不知怎的,它在加入库存之后结束了。奇怪的是,join to MRP的on子句确实紧跟在该表之后。不一致是开发人员的坏习惯。我觉得比“非典型”做事更糟糕。最后,使用alias减少混乱,使代码更易于阅读。更容易阅读意味着你的代码更容易被理解。改进的版本是:

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
您可以对表进行模式限定,这很好——很少看到海报会这样做。但是,它也会使名称非常长,这也是建议使用别名的原因之一

接下来,您将选择“百分之一百前几名”。当你认为你需要这个的时候,停止编写代码,去做一些其他的事情。这是永远不会有用的。如果SSMS试图通过添加它来“修复”某些东西,请不要相信它

您发布的问题是子查询。您试图“修复”原始问题,但没有告诉我们该问题是什么。这是因为查询返回了错误的求和值。为什么会这样?因为您没有将子查询与外部查询关联,所以它为每个单独的库存行计算一个值

要做到这一点,您需要在子查询中删除与库存的联接。为什么?因为适当库存行的键将来自外部查询-这就是如何将内部与外部关联起来。没有GROUPBY子句,因为您的目标是为外部查询中的每一行计算一个值。group by子句从逻辑上指示您打算在该查询中生成多行—这不是您希望发生的(并且不能发生,因为引擎将在该情况下生成错误—您已经发现)。还有一些问题:

  • 别名问题(显然)使子查询难以读取
  • 在当前位置可能不需要使用isnull,但在其他位置需要使用isnull。子查询总是可能找不到匹配的行并返回空值。如果不需要null值,可以使用isnull包装整个子查询。因为你这样做了,所以在你现在拥有它的地方你不需要它。在你目前拥有的地方,它可能不需要用于“匹配”情况——但我不能在不了解你的模式的情况下肯定地说。不管怎样,正确的位置将否定它在求和计算中的必要性
  • where子句中的重复条件。一旦正确关联,就不需要这样做
因此,应用所有这些更改应留下如下内容:

,( 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

希望我没有添加任何打字错误或错误-显然我自己无法检查。但这至少给了你一个更好的起点。您对日期的使用看起来很可疑,但我不知道您的模式或数据,也不知道它是如何使用的,也不知道您查询的目的是什么

是时候重新开始并应用一些最佳编码实践了。您的加入是以“非典型”的方式组织的