查询以显示基于先前交易的股票

时间:2017-01-09 03:24:00

标签: sql sql-server tsql

我需要你的帮助..

目标 将SO(销售订单)数量与采购订单(采购订单)数量基于FIFO(先进先出)进行匹配,其中购买的第一批库存商品必须是销售的第一批商品。

我有一个表格股票,用于跟踪库存进出虚拟仓库的移动。仓库最初是空的,然后库存由于库存购买('IN')而进入仓库,库存在卖出时移出仓库('OUT')。每种类型的库存项目都由ItemID标识。由于购买或销售给定物品,库存进出仓库的每次移动都会导致一行被添加到Stock表中,由StockID标识列中的值唯一标识,并描述有多少项目是添加或删除以及交易日期。

表格库存:

 StockId    DocumentID  ItemID  TranDate    TranCode    Quantity
    ------------------------------------------------------------
    1       PO001       A021    2016.01.01  IN          3
    4       SO010       A021    2016.01.02  OUT         2
    2       PO002       A021    2016.01.10  IN          7
    3       PO003       A021    2016.02.01  IN          9
    5       SO011       A021    2016.02.11  OUT         8
    6       SO012       A023    2016.02.12  OUT         6

如何编写查询以提供如下表所示的输出?

SOID    POID    Quantity
------------------------
SO010   PO001   2
SO011   PO001   1
SO011   PO002   7
SO012   PO003   6

1 个答案:

答案 0 :(得分:0)

所以,看到没有其他人这样做,我想我会发布类似答案的东西(我相信)。

基本上,你要做的是根据日期跟踪你库存的东西的数量和已经出去的东西的数量(我没有考虑到进出的多件事情)但是在同一天)。

DECLARE @Table TABLE 
(
    DocumentID VARCHAR(10) NOT NULL,
    TranCode VARCHAR(3) NOT NULL,
    TranDate DATE NOT NULL,
    Quantity INT NOT NULL
); -- I'm ignoring the other columns here because they don't seem important to your overall needs.

INSERT @Table (DocumentID, TranCode, TranDate, Quantity)
VALUES 
    ('PO001', 'IN', '2016-01-01', 3),
    ('SO010', 'OUT', '2016-01-02', 2),
    ('PO002', 'IN', '2016-01-10', 7),
    ('PO003', 'IN', '2016-02-01', 9),
    ('SO011', 'OUT', '2016-02-11', 8),
    ('SO012', 'OUT', '2016-02-12', 6);

WITH CTE AS
(
    SELECT DocumentID,
            TranCode,
            TranDate,
            Quantity,
            RunningQuantity = -- Determine the current IN/OUT totals.
                (
                    SELECT SUM(Quantity)
                    FROM @Table 
                    WHERE TranCode = T.TranCode
                    AND TranDate <= T.TranDate
                ),
            PrevQuantity = -- Keep track of the previous IN/OUT totals.
                (
                    SELECT ISNULL(SUM(Quantity), 0)
                    FROM @Table
                    WHERE TranCode = T.TranCode
                    AND TranDate < T.TranDate
                )
    FROM @Table T
)
SELECT Outgoing.DocumentID,
        Incoming.DocumentID,
        Quantity =
            CASE WHEN Outgoing.RunningQuantity <= Incoming.RunningQuantity AND Outgoing.PrevQuantity >= Incoming.PrevQuantity
                 THEN Outgoing.RunningQuantity - Outgoing.PrevQuantity
                 WHEN Outgoing.RunningQuantity <= Incoming.RunningQuantity AND Outgoing.PrevQuantity < Incoming.PrevQuantity
                 THEN Outgoing.RunningQuantity - Incoming.PrevQuantity
                 ELSE Incoming.RunningQuantity - Outgoing.PrevQuantity
            END
FROM CTE Outgoing
JOIN CTE Incoming ON
        Incoming.TranCode = 'IN'
    AND Incoming.RunningQuantity > Outgoing.PrevQuantity
    AND Incoming.PrevQuantity < Outgoing.RunningQuantity
WHERE Outgoing.TranCode = 'OUT'
ORDER BY Outgoing.TranDate;

注意:我强烈建议您以更好的方式跟踪信息。例如,创建一个实际详细说明哪些订单取得其他订单(订单交易表或其他内容)的表格,因为虽然根据数据结构的方式实现您想要的并不是不可能的,但如果您只需存储更多有用的数据。