簡體   English   中英

SQL-計算產品的累計平均成本價

[英]SQL - Calculate cumulative average cost price for a product

我想知道是否有人至少可以為我指出這個問題的正確方向。

我需要計算平均庫存成本,但需要注意的是,僅應根據與我們所擁有的庫存有關的最新產品采購來計算。

為了更好地解釋產品x,我們以不同的價格從各種供應商處購買了1200個單位。 我們只剩150個庫存,因此,要獲取平均購買價格和剩余物品的價值,我們需要從購買的150個最新產品中獲取產品的平均成本。

我有一個視圖,它產生以下內容:

 ProductId (int) - PK
 ProductName (varchar(150))
 StockInHand (int)

相關表格如下(為便於使用而被截斷)

采購訂單

PurchaseOrderId (int) - PK
PurchaseOrderDate (DateTime)
PurchaseOrderStatus (int) - FK

采購訂單狀態-1 =打開,2 =簽入

PurchaseOrderLine

PurchaseOrderLineId (int) - PK 
Qty (int)
UnitPrice (decimal(18,2))
ProductId (int) - FK
PurchaseOrderId (int) - FK

UPDATE

我在這里創建了一個sql-fiddle:

http://sqlfiddle.com/#!18/69288/1

您將看到我有三個采購訂單:

1:數量20 @£40ea
2:數量20 @£30ea
3:數量10 @£25ea

我有兩個相同商品的訂單:

1:數量10
2:數量15

由此,我可以獲得庫存: 25

我需要剩下的股票的平均購買價。

我還有25個單位,因此我需要從最新的采購訂單中倒退以獲取價值。

我將從采購訂單3中提取10,從采購訂單2中提取15:

10 * 25英鎊= 250英鎊
15 * 30英鎊= 450英鎊

700英鎊/ 25英鎊= 28英鎊

我希望這使我的問題更清楚!

謝謝

更新2

Sticky Bit非常感謝您抽出寶貴的時間為我的問題發布解決方案,並進行了深思熟慮的解釋。

我已經在我的開發數據庫上嘗試過這個,似乎有問題。

我有4個相同產品的采購訂單(兩個在同一天下達)

我還沒有找到如何在此文本編輯器中優雅地格式化表格的方法,所以請耐心等待:

PurchaseOrderId / PurchaseOrderDate
2 / 2018-07-28
3 / 2018-07-29
4 / 2018-07-30
5 / 2018-07-30

我有以下PurchaseOrderLine

PurchaseOrderLineId / PurchaseOrderId / ProductId / 數量 / 單價
3/2/8 / 200.00
4/3/8/40 / 420.00
5/4/8/25 / 500.00
6/5/5/8 / 10.00

運行以下命令:

SELECT pol.productid,
   po.purchaseorderdate,
   sum(pol.qty) qty,
   avg(pol.unitprice) unitprice
   FROM purchaseorder po
        INNER JOIN purchaseorderline pol
                   ON pol.purchaseorderid = po.purchaseorderid
   GROUP BY pol.productid,
            po.purchaseorderdate;

給我這些結果:

8 2018-07-28 00:00:00.000 20 400.000000
8 2018-07-29 00:00:00.000 40 420.000000
8 2018-07-30 00:00:00.000 26 350.000000

您會注意到,在7月30日購買的產品的平均價格有所下降(它是采用兩個價格之間的平均值,而不考慮數量-我不確定這是否是設計使然?)

如果然后運行以下命令:

SELECT po.productid,
   po.purchaseorderdate,
   sum(po.qty) OVER (PARTITION BY po.productid
                     ORDER BY po.purchaseorderdate) qty,
   sum(po.unitprice) OVER (PARTITION BY po.productid
                           ORDER BY po.purchaseorderdate) unitprice
   FROM (SELECT pol.productid,
                po.purchaseorderdate,
                sum(pol.qty) qty,
                avg(pol.unitprice) unitprice
                FROM purchaseorder po
                     INNER JOIN purchaseorderline pol
                                ON pol.purchaseorderid = po.purchaseorderid
                GROUP BY pol.productid,
                         po.purchaseorderdate) po;

我得到以下結果:

8 2018-07-28 00:00:00.000 20 400.000000
8 2018-07-29 00:00:00.000 60 820.000000
8 2018-07-30 00:00:00.000 86 1170.000000

再次,關於單價似乎有些不對。

任何幫助,不勝感激!

親切的問候

我看不到“ UnitCost”,因此在代碼示例中將使用“ UnitPrice”作為成本。

我不知道這是完美的,但它可能會在正確的方向上為您提供幫助。

SELECT (SUM(UnitPrice)/150) FROM OrderDetails
WHERE PurchaseOrderId IS BETWEEN 1050 AND 1200
GO
  1. 首先,我們需要找到一個查詢以向我們提供每種產品的當前庫存水平。 為此,我們離開加盟purchaseorderlineorderlineproduct ,並計算每行的差異。 由於一個產品可以有多個訂單,因此我們另外匯總結果,以獲得每種產品的總體差異(當前庫存水平)。

     SELECT p.productid, p.productname, sum(coalesce(pol.qty, 0) - coalesce(ol.qty, 0)) qty FROM product p LEFT JOIN purchaseorderline pol ON pol.productid = p.productid LEFT JOIN orderline ol ON ol.productid = p.productid GROUP BY p.productid, p.productname; 
  2. 接下來,我們需要為每種產品和每天( purchaseorders )庫存的數量。 為了實現這一點,我們內部連接了purchaseorderpurchaseorderline 我們再次匯總以考慮可能的情況,即同一天在同一產品上下了多個訂單。

     SELECT pol.productid, po.purchaseorderdate, sum(pol.qty) qty, sum(pol.qty * pol.unitprice) unitprice FROM purchaseorder po INNER JOIN purchaseorderline pol ON pol.purchaseorderid = po.purchaseorderid GROUP BY pol.productid, po.purchaseorderdate; 

    現在,我們可以使用先前的結果和窗口函數來獲取每天庫存量和產品平均價格的總和。

     SELECT po.productid, po.purchaseorderdate, sum(po.qty) OVER (PARTITION BY po.productid ORDER BY po.purchaseorderdate) qty, sum(po.unitprice) OVER (PARTITION BY po.productid ORDER BY po.purchaseorderdate) / sum(po.qty) OVER (PARTITION BY po.productid ORDER BY po.purchaseorderdate) unitprice FROM (SELECT pol.productid, po.purchaseorderdate, sum(pol.qty) qty, sum(pol.qty * pol.unitprice) unitprice FROM purchaseorder po INNER JOIN purchaseorderline pol ON pol.purchaseorderid = po.purchaseorderid GROUP BY pol.productid, po.purchaseorderdate) po; 

現在,我們使用OUTER APPLY將1.和2.的結果放在一起。 對於每種產品,我們從2中選擇TOP 1結果。按降序排列(即先訂購的是年輕訂單),即庫存數量大於或等於當前庫存的數量。

SELECT p.productid,
       p.productname,
       po.unitprice
       FROM (SELECT p.productid,
                    p.productname,
                    sum(coalesce(pol.qty, 0) - coalesce(ol.qty, 0)) qty
                    FROM product p
                         LEFT JOIN purchaseorderline pol
                                   ON pol.productid = p.productid
                         LEFT JOIN orderline ol
                                   ON ol.productid = p.productid
                    GROUP BY p.productid,
                             p.productname) p
            OUTER APPLY (SELECT TOP 1
                                po.unitprice
                                FROM (SELECT po.productid,
                                             po.purchaseorderdate,
                                             sum(po.qty) OVER (PARTITION BY po.productid
                                                               ORDER BY po.purchaseorderdate) qty,
                                             sum(po.unitprice) OVER (PARTITION BY po.productid
                                                                     ORDER BY po.purchaseorderdate)
                                             /
                                             sum(po.qty) OVER (PARTITION BY po.productid
                                                               ORDER BY po.purchaseorderdate) unitprice
                                             FROM (SELECT pol.productid,
                                                          po.purchaseorderdate,
                                                          sum(pol.qty) qty,
                                                          sum(pol.qty * pol.unitprice) unitprice
                                                          FROM purchaseorder po
                                                               INNER JOIN purchaseorderline pol
                                                                          ON pol.purchaseorderid = po.purchaseorderid
                                                          GROUP BY pol.productid,
                                                                   po.purchaseorderdate) po) po
                                WHERE po.productid = p.productid
                                      AND po.qty >= p.qty
                                ORDER BY po.purchaseorderdate DESC) po;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM