【问题标题】:How to distribute sales with partitions如何使用分区分配销售额
【发布时间】:2022-01-14 15:24:51
【问题描述】:

我有 2 张桌子:

第一个表列:ItemCode int、Amount float(我有超过 1000 个 ItemCodes) 第二个表列:ItemCode int、SoldAmount float、Price float(我有超过 10000 个不同商品的销售行)

例子:

ItemId 1528's Amount in 1st table is 244. 第二表中的商品销售额如下:

Sale 1 Amount = 120, Price = 10
Sale 2 Amount = 120, Price = 30
Sale 3 Amount = 100, Price = 20
Sale 4 Amount = 10,  Price = 25
ItemCode Amount
1528 244
1530 150
ItemCode Date Amount Price
1528 2021.11.01 120 10
1530 2021.10.01 120 30
1528 2021.09.01 100 20
1530 2021.08.01 10 25

试过 cursor 和 loop ,但没有想要的输出。

期望的结果是将 100 金额与上述销售额一起分配,如下所示: Sale 1 Amount 60: 100 - 60 = 40 with price 5 --- 所以我们继续下一行并减去剩下的 Sale 2 Amount 30: 40 - 30 = 10 with price 6 --- 所以我们继续下一行并减去剩下的 Sale 3 Amount 20: 10 - 20 = -10 with price 7 --- 所以我们在此停止,因为金额等于 0 或更低。

结果我们应该得到这个:

60 * 5 = 300
30 * 6 = 180
10 * 7 = 70    (that 10 is derived from whatever could be subtracted before it hits 0)

所需表格如下

ItemCode Date Amount Price
1528 2021.11.01 120 10
1528 2021.10.01 120 30
1528 2021.09.01 4 20

我的最后一次尝试如下

WITH CTE AS (

SELECT ItemCode, SUM(Amount) AS Amount
FROM table 1
GROUP BY STOCKREF )

SELECT *,
IIF(LAG(table1.Amount - table2.amount) OVER (PARTITION BY table1.Amount ORDER BY Date DESC) IS NULL, table1.Amount - table2.amount,
LAG(table1.Amount - table2.amount) OVER (PARTITION BY CTE.ItemCode ORDER BY Date DESC) - table2.AMOUNT) AS COL

FROM CTE JOIN (SELECT ItemCode, DATE_, AMOUNT, PRICE FROM table2) table 2 ON table1.ItemCode = table2.Amount

【问题讨论】:

  • 请向minimal reproducible example 提供实际样本数据、预期结果和您的实际尝试。
  • 第一表:ItemCode,金额2,0 6,0 1311,720 1312,6660 1313,2558 1314,5550 1315,4240 1316,6500 ------------ --- 第二个表:ItemCode, Date, SoldAmount, Price 1528,2021-11-29,120,6.76292 1528,2021-11-15,120,6.6453 1528,2021-11-01,100,6.96875 1528,2021-10-18,120,6.1072 ,2021-10-04,125,6.10725 1528,2021-09-20,100,6.36439
  • 感谢回复,但无法正确粘贴表格。如果需要,我可以链接屏幕截图或其他内容
  • 抱歉,无法将数据发布为表格

标签: sql sql-server tsql


【解决方案1】:

希望这解决了正确的问题 - 如果您尝试创建每个 item_code 的运行总计,从第一次到最后一次销售的起始库存中扣除销售数量,也许这会起作用:

CREATE TABLE #items (item_code   INT,
                     item_amount INT);
                    
 INSERT INTO #items (item_code, item_amount)
      VALUES        (1528,      244);
      
 INSERT INTO #items (item_code, item_amount)
       VALUES       (1529,      240);      
  
CREATE TABLE #sales (item_code   INT,
                     sale_date   DATE,
                     sale_amount INT,
                     sale_price  DECIMAL(12,2));
                    
INSERT INTO #sales (item_code, sale_date,    sale_amount, sale_price)
     VALUES        (1528,      '2021-12-01', 50,          5); 
                    
INSERT INTO #sales (item_code, sale_date,    sale_amount, sale_price)
     VALUES        (1528,      '2021-11-29', 120,         6.76292);
      
INSERT INTO #sales (item_code, sale_date,    sale_amount, sale_price)
     VALUES        (1528,      '2021-11-15', 120,         6.6453);        

INSERT INTO #sales (item_code, sale_date,    sale_amount, sale_price)
     VALUES        (1528,      '2021-11-01', 100,         6.96875);        
     
INSERT INTO #sales (item_code, sale_date,    sale_amount, sale_price)
     VALUES        (1529,      '2021-11-30', 48,         7.2);    

INSERT INTO #sales (item_code, sale_date,    sale_amount, sale_price)
     VALUES        (1529,      '2021-11-18', 48,         3.5);         

INSERT INTO #sales (item_code, sale_date,    sale_amount, sale_price)
     VALUES        (1529,      '2021-11-09', 96,         3.9);              

INSERT INTO #sales (item_code, sale_date,    sale_amount, sale_price)
     VALUES        (1529,      '2021-11-05', 96,         3.75); 
      
;WITH all_sales_with_running_totals AS (  --Calculate the running total of each item, deducting sale amount from total starting amount, in order of first sale to last
    SELECT s.item_code,
           s.sale_date,
           s.sale_price,
           i.item_amount AS starting_amount,
           s.sale_amount,
           i.item_amount - SUM(sale_amount) OVER(PARTITION BY s.item_code
                                                     ORDER BY s.sale_date
                                                         ROWS UNBOUNDED PRECEDING
                                            ) AS running_sale_amount
    FROM #sales AS s
    JOIN #items AS i ON s.item_code = i.item_code
),
sales_with_prev_running_total AS (  --Add the previous rows' running total, to assist with the final calculation
    SELECT item_code,
           sale_date,
           sale_price,
           starting_amount,
           sale_amount,
           running_sale_amount,
           LAG(running_sale_amount, 1, NULL) OVER(PARTITION BY item_code
                                                      ORDER BY sale_date
                                             )AS prev_running_sale_amount
      FROM all_sales_with_running_totals
)
SELECT item_code, --Return the final running sale amount for each sale - if the inventory has already run out, return null.  If there is insufficient inventory to fill the order, fill it with the qty remaining.  Otherwise, fill the entire order.
       sale_date,
       sale_price,
       starting_amount,
       sale_amount,
       running_sale_amount,
       prev_running_sale_amount,
       CASE WHEN prev_running_sale_amount <= 0
            THEN NULL
            WHEN running_sale_amount < 0
            THEN prev_running_sale_amount
            ELSE sale_amount
             END AS result_sale_amount
  FROM sales_with_prev_running_total;
       

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-04
    • 2020-02-21
    • 1970-01-01
    相关资源
    最近更新 更多