Mysql 复杂查询

Mysql 复杂查询,mysql,Mysql,我不确定仅仅使用select语句是否可以完成以下操作,但我有两个表被截断,其中包含了解决问题所需的数据 存货项目 id int主 数量整数 库存-包含库存项目库存历史记录中的库存变化 id int主 库存\项目\ id int外键 数量整数 创建日期时间 库存中的数量是库存中的变化,而库存项目中的数量是该项目的当前数量 running列中的所有内容都将返回0 SELECT inventory_item.id, (inventory_item.quantity - SUM(stock.quanti

我不确定仅仅使用select语句是否可以完成以下操作,但我有两个表被截断,其中包含了解决问题所需的数据

存货项目

id int主 数量整数 库存-包含库存项目库存历史记录中的库存变化

id int主 库存\项目\ id 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来执行此操作吗?

更新假设给定的库存项目id和已创建的库存项目id组合不会有多个记录,请尝试:

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

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

在我看来,最清晰的方法是使用相关子查询来获取运行数量。然后,使用where子句选择0的位置就很简单了:

我的看法是:

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;

这种方法的相对优势是只需对stock表进行一次传递。取决于大小和索引,这可能是一件好事,也可能不是一件好事。

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

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

我有一个类似的响应,基于要标记的运行总数

您可以使用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与上一条记录相同,只需使用流动余额并减去该存货分录的数量。

对于给定的库存项目ID和创建的组合,是否会有多条记录?因为i.quantity是最新的数量,这是不正确的。我想你需要把你的跑步场地改成SUMs2.quantity。然后,这将返回所有股票日期的正确结果,而不仅仅是最新的。@Tom:我已经修改了查询,以考虑到您提出的问题。单独使用库存数量之和作为运行总数是不正确的,因为它用于保存库存数量的变化-求和它会告诉我们有多少变化,但不是当时的库存水平。我假设stock.quantity的总和是运行总数,因为他说:库存数量是库存的变化,而库存项目的数量是该项目的当前数量。运行列中的所有内容都将返回0。也许我把这个解释错了?我想股票表中的第一个条目应该是期初股票。如果有或没有完整的股票历史记录,你可以使用它。因此,除非你知道自己有完整的股票历史,否则这可能是最安全的方法。
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