Sql server 2008 求和直到值为零

Sql server 2008 求和直到值为零,sql-server-2008,Sql Server 2008,我有两个问题。 第一个结果是仓库中零件的现有数量: PartNum OnHandQty IUM 100009 19430.00 KG TranDate PartNum TranQty UM Dayss 2014-09-01 100009 10720.000 KG 2 2014-09-01 100009 1340.000 KG 2 2014-08-11 100009 8710.000 KG 23 201

我有两个问题。 第一个结果是仓库中零件的现有数量:

PartNum  OnHandQty  IUM
100009   19430.00   KG
TranDate     PartNum    TranQty     UM  Dayss
2014-09-01   100009     10720.000   KG  2
2014-09-01   100009     1340.000    KG  2
2014-08-11   100009     8710.000    KG  23
2014-08-11   100009     3350.000    KG  23
2014-06-30   100009     9380.000    KG  65
第二次查询的结果是与仓库收货相关的交易:

PartNum  OnHandQty  IUM
100009   19430.00   KG
TranDate     PartNum    TranQty     UM  Dayss
2014-09-01   100009     10720.000   KG  2
2014-09-01   100009     1340.000    KG  2
2014-08-11   100009     8710.000    KG  23
2014-08-11   100009     3350.000    KG  23
2014-06-30   100009     9380.000    KG  65
现在我需要计算OnHandQy-TranQty,直到它达到零,例如

因此,我需要收到如下表格:

PartNum  OnHandQty  IUM  [0-10 Days]  [11-20 Days]   [over 21 Days]
100009   19430.00   KG   12060        null           8710

有没有办法得到这个结果?

一个办法是使用以下查询

WITH(TranDate,PartNum,TranQty,UM,Dayss) trans
AS
(
    -- Your second query
)
SELECT F.PartNum
    ,F.OnHandQty
    ,F.IUM  
    ,SUM(t0to10.TransQty) AS [0-10 Days]
    ,SUM(t11to20.TransQty) AS [11-20 Days]
    ,SUM(tover20.TransQty) AS [over 21 Days]
FROM (Your first query) AS F
    JOIN trans AS t0to10 ON F.PartNum = t0to10.PartNum 
        AND t0to10.Dayss BETWEEN 0 AND 10 
    JOIN trans AS t11to20 ON F.PartNum = t11to20.PartNum 
        AND t11to20.Dayss BETWEEN 11 AND 20
    JOIN trans AS tover20 ON F.PartNum = tover20.PartNum 
        AND tover20.Dayss >20 
GROUP BY F.PartNum,F.OnHandQty,F.IUM  

声明OnHandQty并在while循环中使用光标将有助于解决此问题。

创建一个表示最终输出的临时表,并在while循环中填充它。出于好奇,为什么OnHandQty的精度会精确到小数点后100位?OnHandQty的此精度是因为度量单位并不总是KG
CREATE TABLE #OnHand(
    PartNum  NVARCHAR(100)
    ,OnHandQty DECIMAL
    ,IUM NVARCHAR(5)
    )

INSERT INTO #OnHand
    (PartNum, OnHandQty, IUM)
VALUES  
    ('100009', 19430.00, 'KG')


CREATE TABLE #Trans(
    TranDate DATETIME
    ,PartNum NVARCHAR(100)
    ,TranQty DECIMAL
    ,IUM NVARCHAR(5))

INSERT INTO #Trans
    (TranDate, PartNum, TranQty, IUM)
VALUES
 ('2014-09-01',   '100009',     10720.000,   'KG')
,('2014-09-01',   '100009',     1340.000,    'KG')
,('2014-08-11',   '100009',     8710.000,    'KG')
,('2014-08-11',   '100009',     3350.000,    'KG')
,('2014-06-30',   '100009',     9380.000,    'KG')

DECLARE @OnHand_Running DECIMAL
        ,@OnHandQty DECIMAL
        ,@TranQty DECIMAL
        ,@TranDate DATETIME
        ,@PartNum NVARCHAR(100)
        ,@First10Days INT = 0
        ,@Second10Days INT = 0
        ,@Third10Days INT = 0

SET @PartNum = '100009';

Set @OnHandQty = (Select OnHandQty
                    FROM #OnHand
                    WHERE PartNum = @PartNum)

Set @OnHand_Running = @OnHandQty 

DECLARE tran_cursor CURSOR
    FOR SELECT T.TranQty, T.TranDate
    FROM #Trans T
    ORDER BY T.TranDate DESC
OPEN tran_cursor

FETCH NEXT FROM tran_cursor
INTO @TranQty, @TranDate

WHILE (@@FETCH_STATUS = 0) AND (@OnHandQty > 0)
BEGIN

    IF (@OnHandQty - @TranQty) < 0
    BEGIN
        PRINT CAST(@OnHandQty AS NVARCHAR(100)) + '-' + CAST(@TranQty AS NVARCHAR(100)) + '=' + CAST(@OnHandQty - @TranQty AS NVARCHAR(100)) + '  --Enough'
    END
    ELSE
    BEGIN
        PRINT CAST(@OnHandQty AS NVARCHAR(100)) + '-' + CAST(@TranQty AS NVARCHAR(100)) + '=' + CAST(@OnHandQty - @TranQty AS NVARCHAR(100)) + '  --Not Enough'
    END

    IF (DATEDIFF(DAY, @TranDate, CURRENT_TIMESTAMP) < 10)
    SET @First10Days = @First10Days + @TranQty

    IF (DATEDIFF(DAY, @TranDate, CURRENT_TIMESTAMP) BETWEEN 10 AND 20)
        SET @Second10Days = @Second10Days + @TranQty

    IF (DATEDIFF(DAY, @TranDate, CURRENT_TIMESTAMP) > 20)
        SET @Third10Days = @Third10Days + @TranQty

    SET @OnHandQty = @OnHandQty - @TranQty  

    FETCH NEXT FROM tran_cursor
    INTO @TranQty, @TranDate
END

SELECT @PartNum, @OnHand_Running, 'KG', @First10Days '[0-10] Days', @Second10Days '[11-20] Days', @Third10Days '[over 21 days]' 
CLOSE tran_cursor;
DEALLOCATE tran_cursor;
RETURN