【问题标题】:Storing opening and closing stock best practice存储期初和期末库存最佳实践
【发布时间】:2021-07-06 12:40:28
【问题描述】:

我有 2 个表作为 Inward stock 和 Outward stock。我正在尝试为每个项目创建每日明智的开放、向内、向外和关闭库存。在任何选定的日子,我如何知道前一天的收盘价是多少?然后这成为选定日期的开盘股票。我没有将期初和期末库存存储在单独的表格中,因为我认为它的表格设计不好。

DECLARE @ItemsTable AS TABLE(Item INT,Size INT, Thickness INT, Unit INT);

DECLARE @CalendarItems AS TABLE(Item INT,Size INT,Thickness INT,Unit INT,Date_ DATE);

DECLARE @Inwards AS TABLE(InwardDate DATE, Item INT,Size INT,Thickness INT,Unit INT,Qty DECIMAL(10,2) );

DECLARE @Outwards AS TABLE(OutwardDate DATE, Item INT,Size INT,Thickness INT,Unit INT,Qty DECIMAL(10,2) );

INSERT INTO @ItemsTable
VALUES(1,0,4,19),
    (1,0,4,19),
    (2,0,4,17),
    (2,0,4,17)


     INSERT INTO @CalendarItems
     VALUES(1,0,4,19,'2021-01-14'),
            (1,0,4,19,'2021-01-15'),
            (1,0,4,19,'2021-01-16'),
            (1,0,4,19,'2021-01-17'),
            (2,0,4,17,'2021-01-14'),
            (2,0,4,17,'2021-01-15'),
            (3,0,4,17,'2021-01-16'),
            (4,0,4,17,'2021-01-17')


    INSERT INTO @Inwards
    VALUES('2021-01-14',1,0,4,19,50),
          ('2021-01-15',1,0,4,19,100),
          ('2021-01-14',2,0,4,17,60) 

    INSERT INTO @Outwards
    VALUES('2021-01-15',1,0,4,19,40),
          ('2021-01-16',1,0,4,19,10),
          ('2021-01-16',2,0,4,17,50)
 

    SELECT CT.Date_ [Date], CT.Item, CT.Size, CT.Thickness, CT.Unit, 0.0 Opening, ISNULL(INW.Qty,0) Inward, ISNULL(OW.Qty,0) Outward, 0.0 Closing
    FROM @CalendarItems CT
    LEFT JOIN @Inwards INW ON CT.date_ = INW.InwardDate AND CT.Item = INW.Item AND CT.Size = INW.Size AND CT.Thickness = INW.Thickness AND CT.Unit = INW.Unit 
    LEFT JOIN @Outwards OW ON CT.date_ = OW.OutwardDate AND CT.Item = OW.Item AND CT.Size = OW.Size AND CT.Thickness = OW.Thickness AND CT.Unit = OW.Unit 
  1. 如何获取/计算 21 年 1 月 14 日的期初库存?

  2. 21 年 1 月 14 日的收盘股票与 21 年 1 月 15 日的开盘股票相比如何?

当前结果

+------------+------+------+-----------+------+---------+--------+---------+---------+
| Date       | Item | Size | Thickness | Unit | Opening | Inward | Outward | Closing |
+------------+------+------+-----------+------+---------+--------+---------+---------+
| 2021-01-14 | 1    | 0    | 4         | 19   | 0       | 50     | 0       | 0       |
+------------+------+------+-----------+------+---------+--------+---------+---------+
| 2021-01-15 | 1    | 0    | 4         | 19   | 0       | 100    | 40      | 0       |
+------------+------+------+-----------+------+---------+--------+---------+---------+
| 2021-01-16 | 1    | 0    | 4         | 19   | 0       | 0      | 10      | 0       |
+------------+------+------+-----------+------+---------+--------+---------+---------+
| 2021-01-17 | 1    | 0    | 4         | 19   | 0       | 0      | 0       | 0       |
+------------+------+------+-----------+------+---------+--------+---------+---------+
| 2021-01-14 | 2    | 0    | 4         | 17   | 0       | 60     | 0       | 0       |
+------------+------+------+-----------+------+---------+--------+---------+---------+
| 2021-01-15 | 2    | 0    | 4         | 17   | 0       | 0      | 0       | 0       |
+------------+------+------+-----------+------+---------+--------+---------+---------+
| 2021-01-16 | 3    | 0    | 4         | 17   | 0       | 0      | 0       | 0       |
+------------+------+------+-----------+------+---------+--------+---------+---------+
| 2021-01-17 | 4    | 0    | 4         | 17   | 0       | 0      | 0       | 0       |
+------------+------+------+-----------+------+---------+--------+---------+---------+

预期结果

+------------+------+------+-----------+------+---------+--------+---------+---------+
| Date       | Item | Size | Thickness | Unit | Opening | Inward | Outward | Closing |
+------------+------+------+-----------+------+---------+--------+---------+---------+
| 2021-01-14 | 1    | 0    | 4         | 19   | 0       | 50      | 0       | 50      |
+------------+------+------+-----------+------+---------+--------+---------+---------+
| 2021-01-15 | 1    | 0    | 4         | 19   | 50      | 100    | 40      | 110     |
+------------+------+------+-----------+------+---------+--------+---------+---------+
| 2021-01-16 | 1    | 0    | 4         | 19   | 110     | 0      | 10      | 100     |
+------------+------+------+-----------+------+---------+--------+---------+---------+
| 2021-01-17 | 1    | 0    | 4         | 19   | 100     | 0      | 0       | 100     |
+------------+------+------+-----------+------+---------+--------+---------+---------+
| 2021-01-14 | 2    | 0    | 4         | 17   | 0       | 60     | 0       | 60      |
+------------+------+------+-----------+------+---------+--------+---------+---------+
| 2021-01-15 | 2    | 0    | 4         | 17   | 60      | 0      | 0       | 60      |
+------------+------+------+-----------+------+---------+--------+---------+---------+
| 2021-01-16 | 3    | 0    | 4         | 17   | 0       | 0      | 0       | 0       |
+------------+------+------+-----------+------+---------+--------+---------+---------+
| 2021-01-17 | 4    | 0    | 4         | 17   | 0       | 0      | 0       | 0.0     |
+------------+------+------+-----------+------+---------+--------+---------+---------+

请注意,当项目更改时,期初库存设置为 0

【问题讨论】:

  • 根据问题指南,请不要发布代码、数据、错误消息等的图像 - 将文本复制或输入到问题中。请保留将图像用于图表或演示渲染错误,无法通过文本准确描述的事情。
  • 为什么关店开盘,它们会是一回事?
  • 同意,更新了图片。谢谢!
  • @Charlieface - 目前我没有在任何地方存储打开或关闭。试图从内向外计算。
  • 如果您提供您的 DDL+DML,即声明 CalendarItems 并插入,我们将更容易为您提供帮助。

标签: sql sql-server tsql


【解决方案1】:

使用窗口求和函数将您的给定查询提供给另一个查询:

  1. 开口是Sum(Inward) Over (partition by ItemId, SizeId, ThicknessId, UnitId Order By Date) - Sum(Outward) Over (partition by ItemId, SizeId, ThicknessId, UnitId Order By Date) - Inward + Outward
  2. 关闭是Sum(Inward) Over (partition by ItemId, SizeId, ThicknessId, UnitId Order By Date) - Sum(Outward) Over (partition by ItemId, SizeId, ThicknessId, UnitId Order By Date)

所以,

Select Date,ItemId, SizeId, ThicknessId, UnitId,
       Sum(Inward) Over (partition by ItemId, SizeId, ThicknessId, UnitId Order By Date)
     - Sum(Outward) Over (partition by ItemId, SizeId, ThicknessId, UnitId Order By Date)
     - Inward + Outward as Opening, Inward, Outward,
       Sum(Inward) Over (partition by ItemId, SizeId, ThicknessId, UnitId Order By Date)
     - Sum(Outward) Over (partition by ItemId, SizeId, ThicknessId, UnitId Order By Date)
     As Closing
From (
      SELECT CT.Date_ [Date], CT.Item, CT.Size, CT.Thickness, CT.Unit, 0.0 Opening, ISNULL(INW.Qty,0) Inward, ISNULL(OW.Qty,0) Outward, 0.0 Closing
      FROM @CalendarItems CT
           LEFT JOIN @Inwards INW ON CT.date_ = INW.InwardDate AND CT.Item = INW.Item AND CT.Size = INW.Size AND CT.Thickness = INW.Thickness AND CT.Unit = INW.Unit 
           LEFT JOIN @Outwards OW ON CT.date_ = OW.OutwardDate AND CT.Item = OW.Item AND CT.Size = OW.Size AND CT.Thickness = OW.Thickness AND CT.Unit = OW.Unit
      )
Order By ItemId, SizeId, ThicknessId, UnitId, Date

请注意,这不考虑之前时间段的期初余额 - 它始终以零期初数开始。

【讨论】:

  • 太棒了!你让我今天一整天都感觉很好!我计划在单独的表格中维护每个项目每天的期初和期末库存,以便从前一个时间段获得期初余额。有没有其他更好的方法来获取之前的期初余额而不是存储数据?
  • 从技术上讲,您还可以将这些窗口函数直接移动到您的原始查询中,而根本不用担心外部查询,但我想展示您已经与我们的原始查询有多接近。
  • 不时保存余额快照比从第 0 天重新创建更好的做法。这允许人们进行实物盘点并将错误、损失等修正到表格中,并且所有计算都基于更正后的数字。
  • 完全同意你的看法。我指的是类似的问题和@Tim Biegeleisen 回答说明here。不明白为什么它说它的桌子设计不好。我这里有什么遗漏吗?
  • 从纯理论的角度来看,将记录添加到表中是更紧凑的代码并且更易于维护,理论上您可以进入表并调整 Inward & Outward 以弥补丢失、被盗和错误。但在这种情况下我不同意 - 大多数情况下,在执行实物库存盘点后很难弄清楚你哪里出错了。最好在您的数据库中拥有该库存事件的物理记录。这是对现实的更好反映。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-29
  • 2011-03-23
  • 2021-11-21
  • 2015-09-21
  • 2015-10-11
相关资源
最近更新 更多