【问题标题】:Calculate running profit from average purchase rate and sale rate从平均购买率和销售率计算运行利润
【发布时间】:2018-05-09 16:09:56
【问题描述】:

我正在尝试计算我的利润、产品库存数量和购买和销售的价值。 假设我的购买表为

和我的销售表

目前我已经使用 php 成功完成了。但由于我有超过 100k 的购买和销售,它的工作非常缓慢。所以我需要一个mysql解决方案。下表描述了我的利润/库存计算方法。

  1. 合并购买和销售,然后按日期排序。
  2. 余额存货价值仅取决于平均购买率,而不是销售率。
  3. 利润=(卖出率-平均买入率)*卖出数量

所以我需要在我拿 2017-11-23 的报告时得到

  • 利润 = 602.38
  • 库存数量 = 110
  • 股票价值 = 9052.3806

获得上述结果的快速工作方法是简单的选择查询还是使用存储过程/函数?如果是一个简单的查询更好,应该怎么做?

【问题讨论】:

  • 因此,最后,您希望显示每个产品的每日报告。我说的对吗?
  • 在上表中我只使用了一种产品来轻松了解您的需求。但在我的真实案例中,会有数千种产品。因此,当我获得两个给定日期之间每种产品的总利润、数量和价值时,结果应该按产品 ID 分组。例如 2017-01-01 到 2017-03-31 之间的报告。
  • 我已将我的数据库添加到sqlfiddle.com/#!9/c7ed28/1
  • 我想你之前评论说你想要的是净利润而不是每个产品的利润。

标签: php mysql


【解决方案1】:

到那时,您已经评论说想要每个 Product_id 的结果,我几乎完成了在给定时间范围内显示 Net ProfitStock QuantityStock value 的解决方案。

因此,无论如何,我在这里分享我的方法,因为它可能对您或其他尝试解决此问题的人有所帮助。

解决方案:

select
       final.profit,
       final.Balance_Stock_Quantity,
       final.Balance_Stock_Value
from
(
select tmp.date_,
       tmp.`Sale/Purchase`,
       tmp.product_id,
       tmp.quantity,
       tmp.rate,
       tmp.val,          
(
  case when tmp.`Sale/Purchase` = 'purchase' 
            then (@total_quant := @total_quant + tmp.quantity)
       else      (@total_quant := @total_quant - tmp.quantity)
  end
) as Balance_Stock_Quantity,
(
  case when tmp.`Sale/Purchase` = 'purchase' 
            then (@total_val := @total_val + tmp.val)
       else      (@total_val := @total_val - (@total_rate*tmp.quantity))
  end
) as Balance_Stock_Value,
(
  case when tmp.`Sale/Purchase` = 'purchase' 
            then (@total_rate := @total_val/@total_quant) 
       else @total_rate
  end
) as Balance_Stock_Rate,
(
  case when tmp.`Sale/Purchase` = 'sale' 
            then (@profit := (tmp.rate - @total_rate)*tmp.quantity) 
       else @profit
  end
) as profit

from
(
(select p_date as date_,
       'Purchase' as `Sale/Purchase`,
       p_product_id as product_id,
       p_quantity as quantity,
       p_rate as rate,
       (p_quantity * p_rate) as val
from purchase
where p_date BETWEEN '2017-11-23 00:00:00' AND '2017-11-23 05:00:00'
)
union all
(select s_date as date_,
       'Sale' as `Sale/Purchase`,
       s_product_id as product_id,
       s_quantity as quantity,
       s_rate as rate,
       (s_quantity * s_rate) as val
from sales
where s_date BETWEEN '2017-11-23 00:00:00' AND '2017-11-23 05:00:00' 
)
)tmp
cross join
(select 
        @total_quant := 0,
        @total_val := 0,
        @total_rate := 0, 
        @profit := 0) r
order by tmp.date_
)final
order by final.date_ desc
limit 1
;

DEMO

注意 1:我开始非常兴奋地解决这个问题,因为我发现这是一个具有挑战性的问题,但最后我觉得我基本上在做和你一样的事情已经用一些编程语言完成(例如,像case...when 这样的任务并使用变量来维护ProfitQuantity 等的previous值。

所以我真的不确定,这比你目前的方法效率如何,但我想它仍然值得一试。

注意 2:如果您的目标是显示每个产品的利润、股票和价值,我认为您应该坚持当前的方法。

不过,如果您将Total quantityRateTotal value(显示在您的问题中的第二张图片中)为您的PurchaseSales 表本身中的每个产品存储,这将使您的任务变得容易。如果您负担得起,请计算并存储这些值,同时在这些表中插入其他值。当您为最终报告编写查询时,这将节省大量时间和精力。

希望对你有帮助!

【讨论】:

  • 我正在研究您的查询。但是当我尝试您的查询时,我得到了利润 = 613.1578947368421,Balance_Stock_Quantity = 100,Balance_Stock_Value = 8063.1578947368425,这与我在示例表中显示的不同。它也只是一个单一的产品。我需要在产品方面得到一个结果,作为 array(0=> [product_id= 1], [quantity = 100], [value = 1000][profit = 600], 1 => [product_id = 2], [数量 = 50], [价值 = 750][利润 = 320])
  • 我也修改了链接和查询。请再次浏览我的答案中给出的链接DEMO标题。它将与您的输出相匹配
  • 我已经在回答中声明此查询返回净值。不是每个产品的值。虽然,我在回答中添加了一些要点,如Notes,可以帮助您完成任务。
  • 成功,很好的答案!!。我阅读并喜欢您的建议注意。但我需要通过查询获得相同的每个产品。没办法?
  • 如果您有能力创建和维护一个存储库存寄存器中给出的值的表(您的问题中的第二张图片),那么我想,它可以通过单个 SQL 查询轻松完成。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-19
  • 2013-09-28
相关资源
最近更新 更多