sql >> データベース >  >> RDS >> Sqlserver

CTE - 合計消費されるまで数量を再帰的に更新します

    [email protected] table mimics inserted virtual table from AFTER INSERT triggers on [dbo].[myOrder] table
    DECLARE @inserted TABLE 
    (
      [Account] [float] NOT NULL,
      [Item] [float] NOT NULL,
      [Quantity] [float] NOT NULL
    );
    
    INSERT  @inserted 
    VALUES  (12345, 1, 50);
    
    WITH CteRowNumber
    AS
    (
        SELECT   inv.ID
                ,inv.Account
                ,inv.Item
                ,inv.Quantity
                ,inv.QuantitySold
                ,i.Quantity QuantityOrdered
                ,ROW_NUMBER() OVER(PARTITION BY inv.Account,inv.Item ORDER BY inv.ID ASC) RowNumber
        FROM    myInventory inv
        INNER JOIN @inserted i ON inv.Account = i.Account 
        AND     inv.Item = i.Item 
        WHERE   inv.Quantity > inv.QuantitySold
    ),  CteRecursive
    AS
    (
        SELECT   a.ID
                ,a.Account
                ,a.Item
                ,a.RowNumber 
                ,CASE 
                    WHEN a.Quantity - a.QuantitySold < a.QuantityOrdered THEN a.Quantity - a.QuantitySold 
                    ELSE a.QuantityOrdered
                END QuantitySoldNew
                ,CASE 
                    WHEN a.Quantity - a.QuantitySold < a.QuantityOrdered THEN a.Quantity - a.QuantitySold 
                    ELSE a.QuantityOrdered
                END RunningTotal
        FROM    CteRowNumber a
        WHERE   a.RowNumber = 1
        UNION ALL
        SELECT   crt.ID
                ,crt.Account
                ,crt.Item
                ,crt.RowNumber
                ,CASE 
                    WHEN prev.RunningTotal + (crt.Quantity - crt.QuantitySold) < crt.QuantityOrdered THEN crt.Quantity - crt.QuantitySold
                    ELSE crt.QuantityOrdered - prev.RunningTotal
                END QuantitySoldNew
                ,CASE 
                    WHEN prev.RunningTotal + (crt.Quantity - crt.QuantitySold) < crt.QuantityOrdered THEN prev.RunningTotal + (crt.Quantity - crt.QuantitySold)
                    ELSE crt.QuantityOrdered
                END RunningTotal
        FROM    CteRecursive prev
        INNER JOIN CteRowNumber crt ON prev.Account = crt.Account 
        AND     prev.Item = crt.Item 
        AND     prev.RowNumber + 1 = crt.RowNumber
        WHERE   prev.RunningTotal  < crt.QuantityOrdered
    )
    SELECT   cte.ID
            ,cte.Account
            ,cte.Item
            ,cte.QuantitySoldNew
    FROM    CteRecursive cte;
    --or CteRecursive can be used to update QuantitySold column from [dbo].[myInventory] table
    --UPDATE    myInventory 
    --SET       QuantitySold = inv.QuantitySold + cte.QuantitySoldNew
    --FROM  myInventory inv
    --INNER JOIN CteRecursive cte ON inv.ID = cte.ID;
    



    1. 多くのオラクルで先行ゼロを表示する方法

    2. DISTINCTでIN句の代わりにEXISTSを使用してクエリを最適化することは可能ですか?

    3. Java初心者はデータベース接続の助けが必要です

    4. postgresでISO-8601グレゴリオ暦の日付テーブルを作成する方法