例如,我有下面的表(tb\u事务)
id_trans date_trans production_plant dead_plant distribution_plant
25 2017-12-31 1000 100 200
26 2018-01-17 150 0 0
27 2018-02-07 0 50 100
28 2018-03-07 250 0 75
29 2018-05-10 500 50 0
然后我试着做一个今年的报告表,比如下面的表格
month EarlyStock production dead LivePlant Distri EndStock
January 150 0 150 0 150
February 0 50 -50 100 -150
March 250 0 250 75 175
April 0 0 0 0 0
May 500 50 450 0 450
June 0 0 0 0 0
July 0 0 0 0 0
August 0 0 0 0 0
September 0 0 0 0 0
October 0 0 0 0 0
November 0 0 0 0 0
December 0 0 0 0 0
1月的earlystock是2017年12月的endstock(假设12月的earlystock为0),这是tb\ U交易的第一个数据,而2月的earlystock是endstock 1月,以此类推。
我期望的表格比我想做一个今年的报告表格,像下面的表格
month EarlyStock production dead LivePlant Distri EndStock
January 700 150 0 850 0 850
February 850 0 50 800 100 700
March 700 250 0 950 75 875
April 875 0 0 875 0 875
May 875 500 50 1325 0 1325
June 0 0 0 0 0
July 0 0 0 0 0
August 0 0 0 0 0
September 0 0 0 0 0
October 0 0 0 0 0
November 0 0 0 0 0
December 0 0 0 0 0
公式为:
liveplant=早期库存+生产-死亡
endstock=liveplant-分布
有什么建议我怎么做吗?
这是测试用的小提琴
1条答案
按热度按时间kyks70gy1#
这看起来像一个滚动和问题。在mysql 8.0.2及更高版本中,使用窗口函数可以以不太冗长的方式实现。但是,由于您的mysql版本是5.6,我们可以使用用户定义的会话变量来模拟这种行为。
这项技术的基本要点是:
首先,在派生表中,计算特定年份和月份的各种活动(如死亡、分布等)的合计和值。在您的例子中,您有跨不同年份的数据,因此仅按月份进行分组的方法是行不通的。你需要按年份和月份分组。此外,仅将结果集限制为“当前年度”也无济于事,因为您需要上一年12月的期末股票价值,以便获得下一年1月的早期股票价值。
现在,使用这个子select查询的结果集,并根据给定的定义确定最终库存和早期库存。从概念上讲,这就像编写应用程序代码(例如:php);我们使用前一行的结束库存值作为当前行的早期库存。最后,将结束库存值设置为当前行的结束库存(计算后)。
现在,由于您不希望行对应于上一年;我建议您可以忽略应用程序代码中的那一行。如果您只想在查询中处理它,则仍然是;然后您必须再次将完整的结果集作为派生表,并使用
Where
从年份(而不是当前年份)中筛选出行。尝试以下代码(db fiddle demo):