使用 SQL 创建 2 个带有条件的累积和“墨盒”
Posted
技术标签:
【中文标题】使用 SQL 创建 2 个带有条件的累积和“墨盒”【英文标题】:Creating 2 "cartridges" of cumulative sum with conditions using SQL 【发布时间】:2020-10-25 09:31:28 【问题描述】:我需要根据值类型创建2个累积和,例如:
我有 2 种类型的进货单位的值:A 和 B。我也有出货单位的记录。
如果我们有足够的“A”型库存,则应从 A 型中取出,如果没有,则应从 B 型中取出。所以基本上我需要创建“A 库存”和“B 库存”列下图,代表当前每种类型的余额。
我尝试使用累积和,但我遇到了条件问题...有没有办法在不使用循环的情况下编写此查询? (垂直数据库)
下表中的 A_stock 和 B_stock 是我需要创建的最终结果
ID Type In OUT A stock B stock Order_id
1 A 100 0 100 0 1
1 B 50 0 100 50 2
1 A 100 0 200 50 3
1 - 0 -200 0 50 4
1 - 0 -10 0 40 5
1 B 50 0 0 90 6
1 A 40 0 40 90 7
1 - 0 -20 20 90 8
2 A 30 0 30 0 1
2 B 20 0 30 20 2
2 A 10 0 40 20 3
2 - 0 -20 20 20 4
【问题讨论】:
您的问题似乎表明您的行是有序的。但是,SQL 表代表无序 数据集。除非您明确有一个带有排序的列,否则没有排序。 正如@GMB 指出的那样,您需要一个排序列开始。但是,其次 - 由于以下结果取决于之前发生的任何事情(1. 运行总和;2. 基于先前运行总和和余额的结果的决定),您将需要一个递归查询。而RECURSIVE WITH
子句在 Vertica 中不存在(还没有?)。解决方法是在WITH
子句中编写尽可能多的公用表表达式,因为您期望迭代是必要的。这可能会变得丑陋。
@marcothesane,是的,你当然是对的,要明确的是,我确实有办法对结果进行排序(在示例中添加了排序列)不幸的是我认为你是对的,我没有没有递归查询就没有办法做到这一点......
【参考方案1】:
你可以使用窗口函数——但你需要一个定义行顺序的列,我假设ordering_id
:
select t.*,
sum(case when type = 'A' then in + out else 0 end) over(partition by id order by ordering_id) a_stock,
sum(case when type = 'B' then in + out else 0 end) over(partition by id order by ordering_id) b_stock
from mytable t
这假设您想要以每id
为基础的股票;如果不是这样,只需从over()
子句中删除partition
子句。
【讨论】:
您没有考虑type
列中带有NULL
的行——那些从库存中拿走某些东西并且开始出现决策问题的行,@GMT ... 以上是关于使用 SQL 创建 2 个带有条件的累积和“墨盒”的主要内容,如果未能解决你的问题,请参考以下文章