2012-11-28 52 views
1

我有一个表'我'跟踪库存变化。我用信贷来表示股票和借记的增加来表示减少(我认为从会计原则来看,这是倒退的,但这是客户的期望)。MySQL查询来计算产品ID增量/减量的余额库存水平

我需要计算每个产品(用upc字段表示)的借方和贷方的余额,就像一个正在运行的总额 - 换句话说,我想显示按时间戳排序的日志(或默认顺序) ,并且每当产品有任何增加或减少时,由于该特定增量或减量而显示此时的结果库存余额。

我已经能够证明这一点使用此查询,但只有通过增加其UPC代码在where子句中的条件挑出特定的产品:

SELECT 
    l.id, 
    l.upc, 
    l.credit, 
    l.debit, 
    @bal := @bal + credit - debit AS balance, 
    l.timestamp 
FROM log l, (SELECT @bal := 0) b 
where upc = '677797003424'; 

我有一个fiddle here

问题是,当我删除where子句时,计算没有考虑到它只能分别对每组UPC代码进行操作。

经过一番搜索,我遇到了this question,答案看起来像我可能需要的东西,但是,它不涉及MySQL,而是SQL Server。另外,我不确定结果会是上面提到的日志/跟踪格式。具体来说,我想避免的是在每一行显示最终的平衡。如果库存中有999个产品,后面有4个递减,库存就有995个,那么表示记录递减的每个记录都不应该显示995的计算余额,相反,第一个递减日志应显示结果余额998,第二应显示997等

---编辑---

有没有办法做到这一点,而不使用的变量?另外,是否有可能将日志按时间戳排序,以便产品全部混在一起,而不是一起订购?

回答

0

这会适合你吗?

SELECT 
    l.id, 
    l.upc, 
    l.credit, 
    l.debit, 
    @bal := IF(@previous=l.upc, @bal + l.credit - l.debit, l.credit - l.debit) AS balance, 
    @previous := l.upc, 
    l.timestamp 
FROM `log` l, (SELECT @bal := 0, @previous='') b 
ORDER BY l.upc ASC, l.timestamp ASC 

编辑:

为了获得@bal你可以做负值以下

SELECT 
    l.id, 
    l.upc, 
    l.credit, 
    l.debit, 
    @bal := IF(@previous=l.upc, @bal + l.credit - l.debit, l.credit - l.debit) AS balance, 
    @previous := l.upc, 
    l.timestamp 
FROM `log` l, (SELECT @bal := CAST(0 AS DECIMAL), @previous='') b 
ORDER BY l.upc ASC, l.timestamp ASC 
+0

只要我确认开始贷方余额始终是之前设置可能工作借记开始递减。还有一个问题 - 如果我想首先按时间戳排序,那么产品总是被混淆,而不是一起订购?除了使用变量之外,是否需要另一种方法?如果是这样,是否有可能? –

+0

@LeeFentress我不认为你可以通过直接从mysql获得时间戳,但它是一种简单的列表排序,无论您在后端使用哪种语言(php,ruby等)。至于负值,请参阅我的编辑 – Damp

+0

@LeeFentress不要忘记接受如果您喜欢答案... :) – Damp