在 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 的每一行,按列 Codigo
和 Configuracao
分组。
基本上,我需要一个简单的库存控制,列Codigo
和Configuracao
是产品列控制,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。如果“需要一个简单的库存控制”,我相信你的整个方法是错误的。
- https://en.wikipedia.org/wiki/Double-entry_bookkeeping
- https://medium.com/@RobertKhou/double-entry-accounting-in-a-relational-database-2b7838a5d7f8
我认为您的 table 应该有这样的列:
代理行 ID,primary key
,自动递增整数,32 位或 64 位
列标识您的项目,通常它是一个单一的替代整数 SKU(库存单位)引用(参见 - 外键)另一个“字典 table”。在你的情况下,它似乎是两列 Codigo
和 Configuracao
但这也意味着你不能添加关于你的项目的额外信息(“属性”),如价格或照片(阅读:数据库规范化)。与使用单个整数列相比,它还使 Firebird 引擎的分组更加困难。另外,您确实在项目标识列上创建了一个 index
不是吗?您对这些选择的 查询计划 是什么,它们是在 Codigo
和 Configuracao
上使用索引还是使用临时外部排序?
一个操作的 timestamp
,Firebird 服务器自动将其设置为 current_timestamp
,因此您始终知道插入该行的确切时间。当然是索引。
添加该行的计算机用户,再次由 Firebird 服务器自动设置为 current_user
或某些 stock_workers
table 中的用户 ID你会创造。当然,也有索引。
对某项操作的一些描述,例如合同号或卖家名称,任何可以帮助您日后记住该行描述的真实世界事件的内容。作为自由格式文本,它可能不会被索引。但也许您最终会制作一些 contracts
或 sellers
table 并向这些 table 添加整数引用(FK ID)?这取决于哪种类型的数据会经常重复,值得提取到额外的索引列中。
也许是一个单位,也许你所有的单位永远只能以件来衡量,以整数来衡量。但也许会有一些以公斤、米、升等为单位的物品?
最后两个整数(或浮点数?)列,如 Qty_Income
和 Qty_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 件或更多物品)或任何其他方式灵活地组合类似的请求。
我在计算这个table的最终值时遇到逻辑问题:
https://i.stack.imgur.com/YPXXX.png
我需要计算列 TIPO
值为“E”+1 和“S”-1 的每一行,按列 Codigo
和 Configuracao
分组。
基本上,我需要一个简单的库存控制,列Codigo
和Configuracao
是产品列控制,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。如果“需要一个简单的库存控制”,我相信你的整个方法是错误的。
- https://en.wikipedia.org/wiki/Double-entry_bookkeeping
- https://medium.com/@RobertKhou/double-entry-accounting-in-a-relational-database-2b7838a5d7f8
我认为您的 table 应该有这样的列:
代理行 ID,
primary key
,自动递增整数,32 位或 64 位列标识您的项目,通常它是一个单一的替代整数 SKU(库存单位)引用(参见 - 外键)另一个“字典 table”。在你的情况下,它似乎是两列
Codigo
和Configuracao
但这也意味着你不能添加关于你的项目的额外信息(“属性”),如价格或照片(阅读:数据库规范化)。与使用单个整数列相比,它还使 Firebird 引擎的分组更加困难。另外,您确实在项目标识列上创建了一个index
不是吗?您对这些选择的 查询计划 是什么,它们是在Codigo
和Configuracao
上使用索引还是使用临时外部排序?一个操作的
timestamp
,Firebird 服务器自动将其设置为current_timestamp
,因此您始终知道插入该行的确切时间。当然是索引。添加该行的计算机用户,再次由 Firebird 服务器自动设置为
current_user
或某些stock_workers
table 中的用户 ID你会创造。当然,也有索引。对某项操作的一些描述,例如合同号或卖家名称,任何可以帮助您日后记住该行描述的真实世界事件的内容。作为自由格式文本,它可能不会被索引。但也许您最终会制作一些
contracts
或sellers
table 并向这些 table 添加整数引用(FK ID)?这取决于哪种类型的数据会经常重复,值得提取到额外的索引列中。也许是一个单位,也许你所有的单位永远只能以件来衡量,以整数来衡量。但也许会有一些以公斤、米、升等为单位的物品?
最后两个整数(或浮点数?)列,如
Qty_Income
和Qty_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 件或更多物品)或任何其他方式灵活地组合类似的请求。