You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在分组聚合SQL中计算各分组占全局总和的占比?

分组聚合SQL优化:计算分组占全局总和的比例

现有一条分组聚合SQL,已实现按指定字段分组统计各分组的OrcaItem.Vr_TotalLiquido总和(别名Vr_Liquido),现需计算每个分组的Vr_Liquido占全局Vr_Liquido总和的比例。已知可通过子查询实现,但希望找到更优方案。

当前查询返回简化示例

id|sum
 1| 10
 2| 50
 3| 80
 4| 20
 5| 60

期望返回结果(全局总和为220)

id|sum|     %
 1| 10|10/220
 2| 50|50/220
 3| 80|80/220
 4| 20|20/220
 5| 60|60/220

最优方案:使用窗口函数替代子查询

无需额外子查询,直接用**窗口函数SUM() OVER ()**即可高效计算全局总和,避免重复扫描数据表,性能更优。

修改后的完整SQL

Select
   OrcaItem.Cd_Produto,
   OrcaItem.Ds_Produto,
   OrcaItem.Cd_Produto || ' - ' || OrcaItem.Ds_Produto CdDs_Produto,
   Estoque.Qt_Disponivel,
   Sum(OrcaItem.Qt_Vendida) Qt_Vendida,
   Sum(OrcaItem.Vr_TotalLiquido) Vr_Liquido,
   -- 新增:计算分组占全局总和的比例(数值形式,保留4位小数)
   Cast(Sum(OrcaItem.Vr_TotalLiquido) / Sum(Sum(OrcaItem.Vr_TotalLiquido)) OVER () As Numeric(10,4)) Pc_Liquido,
   -- 可选:按示例格式显示为"分子/分母"的字符串形式
   Cast(Sum(OrcaItem.Vr_TotalLiquido) As Varchar) || '/' || Cast(Sum(Sum(OrcaItem.Vr_TotalLiquido)) OVER () As Varchar) Pc_Liquido_Text,
   Cast(Sum(
      Case :piTipoCusto
         When 0 Then (Produto.Vr_CustoAtual * OrcaItem.Qt_Vendida)
         When 1 Then (OrcaItem.Vr_CustoAtual * OrcaItem.Qt_Vendida)
         When 2 Then (OrcaItem.Vr_CustoFin * OrcaItem.Qt_Vendida)
         When 3 Then (Produto.Vr_UltPcoCompra * OrcaItem.Qt_Vendida)
      End
   ) As Numeric(15,2)) Vr_Custo,
   Cast(Sum(
      Case :piTipoCusto
         When 0 Then OrcaItem.Vr_TotalLiquido - (Produto.Vr_CustoAtual * OrcaItem.Qt_Vendida)
         When 1 Then OrcaItem.Vr_TotalLiquido - (OrcaItem.Vr_CustoAtual * OrcaItem.Qt_Vendida)
         When 2 Then OrcaItem.Vr_TotalLiquido - (OrcaItem.Vr_CustoFin * OrcaItem.Qt_Vendida)
         When 3 Then OrcaItem.Vr_TotalLiquido - (Produto.Vr_UltPcoCompra * OrcaItem.Qt_Vendida)
      End
   ) As Numeric(15,2)) Vr_Lucro,
   Sum(
      Case :piTipoCusto
         When 0 Then OrcaItem.Vr_TotalLiquido - (Produto.Vr_CustoAtual * OrcaItem.Qt_Vendida)
         When 1 Then OrcaItem.Vr_TotalLiquido - (OrcaItem.Vr_CustoAtual * OrcaItem.Qt_Vendida)
         When 2 Then OrcaItem.Vr_TotalLiquido - (OrcaItem.Vr_CustoFin * OrcaItem.Qt_Vendida)
         When 3 Then OrcaItem.Vr_TotalLiquido - (Produto.Vr_UltPcoCompra * OrcaItem.Qt_Vendida)
      End
   ) / Sum(OrcaItem.Vr_TotalLiquido) * 100 Pc_Lucro,
   Produto.Cd_Linha,
   Linha.Ds_Linha,
   Produto.Cd_Grupo,
   Grupo.Ds_Grupo
From
   OrcaItem
Inner Join Orca On Orca.Nr_Orcamento = OrcaItem.Nr_Orcamento
Inner Join Estoque On Estoque.Cd_Produto = OrcaItem.Cd_Produto
Inner Join Produto On Produto.Cd_Produto = OrcaItem.Cd_Produto
Inner Join Linha On Linha.Cd_Linha = Produto.Cd_Linha
Inner Join Grupo On Grupo.Cd_Linha = Produto.Cd_Linha And
                    Grupo.Cd_Grupo = Produto.Cd_Grupo
Where
   Orca.Fg_Situacao In ('F', 'R') And
   Orca.Dt_Atendido Between :piDt_Inicio And :piDt_Final
Group By
   OrcaItem.Cd_Produto,
   OrcaItem.Ds_Produto,
   CdDs_Produto,
   Estoque.Qt_Disponivel,
   Produto.Cd_Linha,
   Linha.Ds_Linha,
   Produto.Cd_Grupo,
   Grupo.Ds_Grupo
Order By
   Produto.Cd_Linha,
   Produto.Cd_Grupo,
   OrcaItem.Ds_Produto

关键说明

  • Sum(Sum(OrcaItem.Vr_TotalLiquido)) OVER ():内层Sum是分组聚合得到的每个分组的Vr_Liquido,外层Sum结合OVER ()(不指定分区,覆盖整个结果集)计算出全局总和。
  • 若需要百分比形式,可将数值比例乘以100,比如Cast(Sum(OrcaItem.Vr_TotalLiquido)/Sum(Sum(OrcaItem.Vr_TotalLiquido)) OVER ()*100 As Numeric(10,2)) || '%' Pc_Liquido_Pct。

内容的提问来源于stack exchange,提问作者Roberto Henrique

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 17:25:50