SQL HAVING SUM GROUP BY

4
使用SQL Server 2005。我正在构建一个库存/采购程序,现在需要用户“签出”设备。当他选择一个产品时,我需要查询哪些库存位置有可用数量,并告诉用户要去哪个位置/检索产品。
以下是针对特定的[StockLocation_Products].ProductID和特定分配的[ProductUsages].ProductUsageID的查询。
SELECT 
  PROD.ProductID,
  PROD.ProductName,
  SL.Room,
  SL.StockSpace,
  SLPPU.ResvQty,
  PRDUSG.ProductUsage
FROM [StockLocations] SL 
INNER JOIN [StockLocation_Products] SLP ON SL.StockLocationID = SLP.StockLocationID 
INNER JOIN [StockLocation_Product_ProductUsages] SLPPU ON SLP.StockLocationID = SLPPU.StockLocationID AND SLP.ProductID = SLPPU.ProductID 
INNER JOIN [ProductUsages] PUSG ON SLPPU.ProductUsageID = PRDUSG.ProductUsageID 
INNER JOIN [Products] PROD ON SLPPU.ProductID = PROD.ProductID
WHERE SLP.ProductID = 4 AND PRDUSG.ProductUsageID = 1

这个查询返回:

ProductID ProductName           Room    StockSpace  ResvQty ProductUsage
------------------------------------------------------------------------------------------------------------------------
4   Addonics Pocket DVD+/-R/RW  B700    5-D         12      MC Pool
4   Addonics Pocket DVD+/-R/RW  B700    6-B         10      MC Pool
4   Addonics Pocket DVD+/-R/RW  B700    6-C         21      MC Pool
4   Addonics Pocket DVD+/-R/RW  B700    6-D         20      MC Pool

我想也许可以加入额外的 HAVING 子句来使这个查询返回满足请求某些数量所需访问的 StockSpace 组合。例如,用户需要取 30 个产品(ID = 4)。
但我真的不明白如何使用带有 SUM() 的 GROUP BY 和 HAVING 来实现我想要的结果。
我尝试在我的 GROUP BY / HAVING 子句中尝试了各种方法,但我只是得不到任何结果。
GROUP BY PROD.ProductID,PROD.ProductName,SL.Room,SL.StockSpace,SLPPU.ResvQty,PUSG.ProductUsage
HAVING SUM(ResvQty) >= 30;

我希望能够找到至少一种组合,使得StockSpaces的总和为30。这样我就可以告诉用户:“您可以从‘6-C’空间获得21个单位,并从‘6-B’获得9个单位。”可能有多种行的组合可以使sum()>=30,但我需要至少找到一种可以实现的组合!请帮助我!
2个回答

2
您可以使用内部选择器,例如:
SELECT count_of_foo, count(bar), baz
FROM (SELECT count(foo) as count_of_foo, bar, baz, other1, other2 FROM complex_query WHERE foo = bar HAVING count(foo) > 1) inner_query
GROUP BY count_of_foo, baz.

这将使您能够在HAVING子句之后添加更多的分组依据。

1
抱歉,可能是因为我太新了,但所有的foo,bar,baz等对我没有帮助。 - mhz.NET

0

你想要做的是一个累加和,这可以通过 SQL 中的各种技术来实现。我认为最有效的查询方式,特别是如果你想在同一个查询中完成所有操作,是使用 CTE(这里有一个例子)。

另一种技术 不依赖于 CTE,需要将数据填充到另一个表中(可以是临时表),然后基本上进行联接和排序操作。

一旦你得到了包含累加和的数据,那么你就可以简单地选择从中运行总和小于或等于你要查找的总数的值。

这里则是对几种不同技术的一个很好的总结。


你给了我一个可以参考的概念,而我找到的最清晰的例子是在http://dev.mysql.com/tech-resources/articles/rolling_sums_in_mysql.htm。虽然他使用的是MySQL,但那位作者确实比其他你提供的链接更清楚地解释了这个概念。
"一旦你加入了一个累积和,你就可以选择那些累积和小于或等于你想要定位的总数的值。"
这个句子帮助我完成了在跟随他的示例之后的工作。谢谢。
- mhz.NET
抱歉,该链接缺少尾随的“L”。应该是: http://dev.mysql.com/tech-resources/articles/rolling_sums_in_mysql.html - mhz.NET
遗憾的是,我注意到链接的网页文章已经消失了。mysql.com 网站似乎删除了这些非常有用的内容。 - mhz.NET
使用Wayback Machine:https://web.archive.org/web/20100311073314/http://dev.mysql.com/tech-resources/articles/rolling_sums_in_mysql.html - Joe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接