【问题标题】:How Do I Find the Minimum Value of a Running Total by Group In SQL?如何在 SQL 中按组查找运行总计的最小值?
【发布时间】:2020-11-06 10:35:54
【问题描述】:

我是所有 excel 和 power query 的长期用户,但在 SQL 方面我完全是一个脑残的菜鸟。

我的项目的目标是按组找到运行总计中的最小值。

我已经能够弄清楚如何计算基本运行总计。我的下一个想法是针对我的运行总计查询运行另一个查询,其中我在运行总计列上运行另一个聚合函数以返回最小值。当我这样做时,查询将永远旋转,然后返回错误...

我会注意到我正在 MS Access 中创建 SQL 代码,因为我目前无法访问我可以在工作中使用的 SQL 服务器。

所以首先我创建一个联合查询来将多个表组合在一起并将该查询称为“组合”:

    SELECT [ItemCode], '1/1/2010' as [Date], 'IM' as [Type], [WarehouseCode], [QuantityOnHand] as [Qty]
    FROM [IM_ItemWarehouse]
    
    UNION ALL
    
    SELECT [ItemCode], [RequiredDate] as [Date], 'PO' as [Type], [WarehouseCode], [QuantityOrdered] - [QuantityReceived] as [Qty]
    FROM [PO_PurchaseOrderDetail]
    WHERE [QuantityOrdered] - [QuantityReceived] > 0

    UNION ALL 

    SELECT [ItemCode], [PromiseDate] as [Date], 'SO' as [Type], [WarehouseCode], ([QuantityOrdered] - 
    [QuantityShipped])*-1 as [Qty]
    FROM [SO_SalesOrderDetail]
    WHERE [QuantityOrdered] - [QuantityShipped] > 0;

然后我去 oldschool 并使用嵌套的 select 语句来计算我的运行总计并将此查询称为“RunTotal”:

    SELECT t1.[ItemCode], t1.[WarehouseCode], t1.[Date], sum(t1.[Qty]) AS TotalByDate, (SELECT
    sum(t2.[Qty])
    FROM Combined t2
    WHERE t2.[ItemCode] = t1.[ItemCode] AND t2.[WarehouseCode] = t1.[WarehouseCode] AND t2.[Date] <= t1.[Date]) AS RunningTotal
    FROM Combined t1
    GROUP BY t1.[ItemCode], t1.[WarehouseCode], t1.[Date]
    ORDER BY t1.[ItemCode], t1.[WarehouseCode], t1.[Date];

然后...卡住了...这是我尝试过的,但到目前为止,查询只是永远旋转或返回错误:

    SELECT [ItemCode], [WarehouseCode], min([RunningTotal])
    FROM RunTotal
    GROUP BY [ItemCode], [WarehouseCode];

提前感谢您提供的任何帮助...我知道使用窗口函数可以更有效地计算运行总和,但是由于我在 MS Access 中编写这些 SQL 语句,所以我没有访问性感花哨的东西,如 OVER 和 PARTITION BY...

示例基础数据:

Style   Type    Whs Date        Qty
widget  On Hand NVR 1/1/2010    100
widget  On SO   NVR 7/15/2020   -30
widget  On PO   NVR 7/18/2020   50
widget  On SO   NVR 7/19/2020   -10
widget  On SO   NVR 7/20/2020   -60
gizmo   On Hand NVR 1/1/2010    100
gizmo   On SO   NVR 7/15/2020   -100
gizmo   On PO   NVR 7/18/2020   50
gizmo   On SO   NVR 7/19/2020   -20
gizmo   On SO   NVR 7/20/2020   -30

示例运行总计:

Style   Type    Whs Date        Qty  RunTotal
widget  On Hand NVR 1/1/2010    100  100 
widget  On SO   NVR 7/15/2020   -30  70 
widget  On PO   NVR 7/18/2020   50   120 
widget  On SO   NVR 7/19/2020   -10  110 
widget  On SO   NVR 7/20/2020   -60  50 
gizmo   On Hand NVR 1/1/2010    100  100 
gizmo   On SO   NVR 7/15/2020   -90  10 
gizmo   On PO   NVR 7/18/2020   50   60 
gizmo   On SO   NVR 7/19/2020   -20  40 
gizmo   On SO   NVR 7/20/2020   -10  30 

示例最终结果:

Style   Whs MinRunTotal
widget  NVR 50
gizmo   NVR 10

【问题讨论】:

  • 样本数据和期望的结果会很有帮助。
  • @GordonLinoff 我已经更新了我的帖子...谢谢您的建议...嗯,这会很有帮助...我的坏...
  • 您可能必须将运行总和数据写入临时表,然后在该表中查询最小值。
  • 日期是保留字(内在函数)。不应使用保留字作为名称。

标签: sql ms-access group-by aggregate cumulative-sum


【解决方案1】:

从语法上讲,您的第一个查询无法在 MS Access 中编译,因为 RunningTotal 相关聚合表达式应包含在 GROUP BY 子句中。但实际上,GROUP BY 中可能不允许关联子查询,并且您也不想在聚合期间按此排名计算进行分组。。此外,在 MS Access 中,对底层 UNION 查询运行复杂操作确实会产生性能问题。

考虑以下设置:

  1. 将底层联合查询转换为临时表:

    SELECT * INTO mytemptable FROM myUnionQuery
    
  2. 计算运行总计(准聚合)。

    SELECT t.[ItemCode], t.[WarehouseCode], t.[Date], 
           (SELECT SUM(sub.[Qty]) FROM myTempTable sub
            WHERE sub.[ItemCode] = t.[ItemCode] 
              AND sub.[WarehouseCode] = t.[WarehouseCode]
              AND sub.[Date] <= t.[Date]) AS RunningQtyTotal
    FROM myTempTable t;
    
  3. [ItemCode][WarehouseCode] 级别聚合:

    SELECT q.[ItemCode], q.[WarehouseCode], MIN(q.[RunningQtyTotal]) AS MinRunQtyTotal
    FROM mySelectQuery q
    GROUP BY q.[ItemCode], q.[WarehouseCode]
    

【讨论】:

  • 非常感谢您对我的问题的深思熟虑的回答...我非常感谢您抽出时间阅读和消化我的文字墙。创建一个临时表并从该临时表计算运行总计非常聪明!并且肯定加快了初始计算。我想我也可以为辅助计算制作一个临时表,并从该临时表中聚合第 3 步……因为最终聚合仍然很慢(完整数据集大约有 44,000 条记录)跨度>
  • 听起来不错。乐意效劳。是的,根据需要使用临时表。相关的聚合查询并不是最好的性能。也许有一天,Access 团队将根据我的suggestion 支持窗口函数以及其他当前 SQL 功能。
  • 这个建议太棒了。来吧 MS Access ......没有意识到这种语言已经过时了!哦,我在复制您的建议时注意到的一件事是,在第 2 步中,SUM(t2.[Qty] 缺少一个封闭的括号,并且也应该是 SUM(sub.[Qty]),因为您将两个表的命名从t1 和 t2 到 t 和 sub(我更喜欢你的命名法...更容易理解)
猜你喜欢
  • 2014-04-05
  • 2021-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-21
  • 2018-03-04
  • 2018-03-21
  • 2021-01-15
相关资源
最近更新 更多