8

我不确定是否可以仅使用 select 语句完成以下操作,但我有两个表(截断了问题所需的数据)。

库存项目

  • id int(主要)
  • 数量int

库存- 包含库存项目的库存变化(库存历史)

  • id int(主要)
  • inventory_item_id int(外键)
  • 数量int
  • 创建日期时间

库存数量是库存的变化,而库存项目的数量是该项目的当前数量

列中的running所有内容都将返回 0

SELECT
inventory_item.id,
(inventory_item.quantity - SUM(stock.quantity)) AS running
FROM
    stock
        JOIN
    inventory_item ON stock.inventory_item_id = inventory_item.id
GROUP BY inventory_item.id

问题

现在,我想知道的是:是否可以使用 SELECT 选择库存表中库存项目的运行数量变为零的所有日期?

我知道这可以通过简单地选择一个项目中的所有库存数据以编程方式完成,然后从当前库存项目数量中单独减去库存数量,这将获得库存变化发生之前的数量。我可以用 SELECT 来做到这一点吗?

4

5 回答 5

5

(更新)假设给定的inventory_item_id和created组合永远不会有多个记录,请尝试:

SELECT i.id,
       s.created,
       i.quantity - COALESCE(SUM(s2.quantity),0) AS running
FROM inventory_item i
JOIN stock s ON s.inventory_item_id = i.id
LEFT JOIN stock s2 ON s2.inventory_item_id = i.id and s.created < s2.created
GROUP BY i.id, s.created
HAVING running=0
于 2013-07-01T17:22:59.610 回答
2

最合乎逻辑的方法是使用累积和。但是,MySQL 不支持。

在我看来,最清晰的方法是使用相关子查询来获取运行量。where然后选择它在哪里是一个简单的子句0

select i.*
from (select i.*,
             (select SUM(i2.inventory)
              from inventory i2
              where i2.inventory_item_id = i.inventory_item_id and
                    i2.created <= i.created
             ) as RunningQuantity
      from inventory i
     ) i
 where RunningQuantity = 0;
于 2013-07-01T17:25:47.570 回答
2

我的看法:

select
    inventory_item_id `item`,
    created `when`
from
    (select 
         @total := CASE WHEN @curr <> inventory_item_id
                   THEN quantity
                   ELSE @total+quantity END as running_total,
         inventory_item_id,
         created,                   
         @curr := inventory_item_id
     from
         (select @total := 0) a
         (select @curr  := -1) b
         (select inventory_item_id, created, quantity from stock order by inventory_item_id, created asc) c
     ) running_total
where running_total.running_total = 0;

这个相对优势是只需要给股票表一次通行证。取决于它的大小和索引,这可能是也可能不是一件好事。

于 2013-07-01T17:28:38.090 回答
2

我相信这是一个简单的方法。

SELECT inventory_item.id, stock.created

FROM   inventory_item

       JOIN stock ON stock.inventory_item_id = inventory_item.id

WHERE  (SELECT SUM(quantity) FROM stock WHERE created <= stock.created) = 0
于 2013-07-01T17:30:07.483 回答
2

我有一个类似的响应,基于要在此处找到的运行总数...

您可以使用 MySQL @variables,但数据需要预先查询并按活动数据排序......然后在每一行上设置一个导致负数的标志并只保留那些。就像是

select 
      PreQuery.*
   from 
      ( select
              s.id,
              s.created,
              @runBal := if( s.id = @lastID, @runBal - quantity, @i.quantity ) as CurBal,
              @lastID := s.id as IDToCompareNextEntry
           from
              stock s
                 join inventory_item ii
                    on s.inventory_item_id = ii.id,
              (select @lastID := -1,
                      @runBal := 0 ) sqlvars
           order by
              s.id,
              s.created DESC ) PreQuery
   where
      PreQuery.CurBal < 0

这样,对于每个库存项目,它按创建日期向后工作(按创建的每个 ID 降序排列)。因此,当库存 ID 更改时,请查看库存表的“数量”字段以开始计算已用库存。如果与处理的最后一条记录相同的 ID,则只需使用运行余额并减去该库存条目的数量。

于 2013-07-01T17:31:33.240 回答