在 firebird 中使用 group by 从 1 table 计算值的问题

Problem to calculate values from 1 table using group by in firebird

我在计算这个table的最终值时遇到逻辑问题:

https://i.stack.imgur.com/YPXXX.png

我需要计算列 TIPO 值为“E”+1 和“S”-1 的每一行,按列 CodigoConfiguracao 分组。

基本上,我需要一个简单的库存控制,列CodigoConfiguracao是产品列控制,TIPO是运动类型,S = OUT和E =在

谁能给我点灯?

未经测试但可能是这个

select SUM(t1.TipoNumeric), t1.CODIGO, t1.CONFIGURACAO from (
   select 
       case (TIPO)
           when 'E' then 1
           when 'S' then -1
           else 0
       end as TipoNumeric,
       CODIGO,
       CONFIGURACAO
   from MyTable
) as t1
group by t1.CODIGO, t1.CONFIGURACAO

也许只需添加 +1/-1 列?

alter table MyTable 
  add tipo_val computed by
  (  
    decode( upper(TIPO), 'E', +1, 'S', -1 )
  )

然后:

Select * from MyTable;

Select SUM(tipo_val), CODIGO, CONFIGURACAO
From MyTable
Group by 2, 3

P.S。不要用图片来展示你的数据。

而是将它们作为脚本放入 http://dbfiddle.uk/?rdbms=firebird_3.0, 然后在那里使用 Markdown Export 将数据和超链接复制到您的问题文本中。

P.P.S。如果“需要一个简单的库存控制”,我相信你的整个方法是错误的。

我认为您的 table 应该有这样的列:

  • 代理行 ID,primary key,自动递增整数,32 位或 64 位

  • 列标识您的项目,通常它是一个单一的替代整数 SKU(库存单位)引用(参见 - 外键)另一个“字典 table”。在你的情况下,它似乎是两列 CodigoConfiguracao 但这也意味着你不能添加关于你的项目的额外信息(“属性”),如价格或照片(阅读:数据库规范化)。与使用单个整数列相比,它还使 Firebird 引擎的分组更加困难。另外,您确实在项目标识列上创建了一个 index 不是吗?您对这些选择的 查询计划 是什么,它们是在 CodigoConfiguracao 上使用索引还是使用临时外部排序?

  • 一个操作的 timestamp,Firebird 服务器自动将其设置为 current_timestamp,因此您始终知道插入该行的确切时间。当然是索引。

  • 添加该行的计算机用户,再次由 Firebird 服务器自动设置为 current_user 或某些 stock_workers table 中的用户 ID你会创造。当然,也有索引。

  • 对某项操作的一些描述,例如合同号或卖家名称,任何可以帮助您日后记住该行描述的真实世界事件的内容。作为自由格式文本,它可能不会被索引。但也许您最终会制作一些 contractssellers table 并向这些 table 添加整数引用(FK ID)?这取决于哪种类型的数据会经常重复,值得提取到额外的索引列中。

  • 也许是一个单位,也许你所有的单位永远只能以件来衡量,以整数来衡量。但也许会有一些以公斤、米、升等为单位的物品?

  • 最后两个整数(或浮点数?)列,如 Qty_IncomeQty_Outcome,您可以在其中记录从您的仓库中添加或取出的项目数量。会有 而不是 那 E/S 列!将有两个整数列,您可以将数字放入一个或另一个中。为什么?阅读上面有关簿记的文章!

在这样的数据库方案中,您的查询最终将如下所示:

select Sum(s.Qty_Income) as Credit, Sum(s.Qty_Outcome) as Debit,
       Sum(s.Qty_Income) - Sum(s.Qty_Outcome) as Saldo,
       min(g.Codigo), min(g.Configuracao)
from stock_movements s
       join known_goods g on g.ID = s.SKU_ID 
group by s.SKU_ID

而且您还可以根据工作人员、日期或数量(例如,只关心大事件,例如在一次操作中添加 1000 件或更多物品)或任何其他方式灵活地组合类似的请求。