【问题标题】:How to obtain Additions and Deductions from table如何从表中获得加减
【发布时间】:2018-10-05 06:44:06
【问题描述】:

我有这张表来存储销售订单。场景是,一旦任何销售订单被打孔,它就不会最终确定,并且需要稍后进行编辑,因此如果添加并再次保存更多项目,销售订单将更新交易编号比前一个交易编号更多,以跟踪更改.这是一个示例数据,销售订单被打孔,然后添加了 2 倍以上的项目并更改了金额,并且在最后一行中显示的项目被取消并更改了金额。 我想计算每次添加新商品时在销售订单中添加的数量以及取消的商品数量以及取消的商品价值。

CREATE TABLE SaleOrder
    (
    TransactionNo Int,
    SaleOrderDate DATE,
    Code VARCHAR(25),
    Quantity INT,
    TotalAmount Numeric(18,2),
    Remarks VARCHAR(25)
    )

INSERT INTO SaleOrder VALUES (NULL, '2018-10-01', 'SO-001-OCT-18', 6, '2500', 'Hello');
INSERT INTO SaleOrder VALUES (1, '2018-10-01', 'SO-001-OCT-18', 8, '2600', 'Hello');
INSERT INTO SaleOrder VALUES (2, '2018-10-01', 'SO-001-OCT-18', 12, '3400', 'Hello');
INSERT INTO SaleOrder VALUES (3, '2018-10-01', 'SO-001-OCT-18', 9, '2900', 'Hello');

这将是我所期望的结果。

Code           SaleOrderDate  Quantity InitialAmount Addition   Cancellation
SO-001-OCT-18  2018-10-01     9        2500.00       900.00     500.00

我已经写了这个查询,但它没有那么大的帮助。

;WITH CTE AS (
SELECT 
[TransactionNo], [Code], [SaleOrderDate], [Quantity], [TotalAmount],
CAST('Oct  1 2018 10:16AM' AS DATE) AS [DateFrom], CAST('Oct  4 2018 10:16AM' AS DATE) AS [DateTo]

FROM [SaleOrder]

GROUP BY 
[TransactionNo], [Code], [SaleOrderDate], [TotalAmount], Quantity
)

SELECT 
    [D].[TransactionNo], [D].[Code], [D].[SaleOrderDate], [D].[Quantity], [D].TotalAmount, 

    --CAST('Oct  4 2018  4:06PM' AS DATE) AS [DateFrom],
    --CAST('Oct  4 2018  4:06PM' AS DATE) AS [DateTo],   
    [D].[Balance], [D].[Balance]-ISNULL(NULLIF([D].TotalAmount, 0),0) [Opening]

FROM(
    SELECT *,
           SUM(TotalAmount) OVER (PARTITION BY [Code] ORDER BY [TransactionNo], [SaleOrderDate]) AS [Balance]
    FROM CTE 

    )D

    WHERE [SaleOrderDate] BETWEEN CAST('Oct  1 2018 10:16AM' AS DATE) AND CAST('Oct  4 2018 10:16AM' AS DATE)

    ORDER BY [SaleOrderDate]

【问题讨论】:

  • 我不明白您是如何得出这些增加和取消金额的。你能解释一下你的预期输出背后的逻辑吗?
  • @TimBiegeleisen 正如我在上面解释的Additions 是稍后添加到销售订单中的金额,就像我创建了2500 的订单一样,但后来意识到要添加更多东西,现在是订单分别变为26003400。然后由于某些原因,我不得不删除一些项目,现在删除这些项目的订单总量现在是2900。所以初始订单量是2500,我添加了900,一次100,然后800。然后在最后一行也取消了500

标签: sql-server


【解决方案1】:

使用LAG() 窗口函数获取先前的值并进行比较以确定它是添加还是取消。

; WITH cte as
(
    SELECT  *,
            row_no      = ROW_NUMBER() OVER (PARTITION BY Code ORDER BY TransactionNo DESC),
            Addition    = CASE WHEN TotalAmount > LAG(TotalAmount) OVER (PARTITION BY Code ORDER BY TransactionNo)
                               THEN TotalAmount - LAG(TotalAmount) OVER (PARTITION BY Code ORDER BY TransactionNo)
                               ELSE 0
                               END,
            Cancellation = CASE WHEN    TotalAmount < LAG(TotalAmount) OVER (PARTITION BY Code ORDER BY TransactionNo)
                                THEN    LAG(TotalAmount) OVER (PARTITION BY Code ORDER BY TransactionNo) - TotalAmount
                                ELSE    0
                                END
    FROM    SaleOrder
)
SELECT  Code,  
        SaleOrderDate,
        Quantity    = MAX (CASE WHEN row_no  = 1 then Quantity END),
        InitialAmount   = MAX (CASE WHEN TransactionNo IS NULL THEN TotalAmount END),
        Addition    = SUM (Addition),
        Cancellation    = SUM (Cancellation)
FROM    cte
GROUP BY Code, SaleOrderDate

【讨论】:

    【解决方案2】:

    你想这样做吗? :

    SELECT 
        Code
    ,   MAX(SaleOrderDate) SaleOrderDate
    ,   MAX(Quantity) Quantity
    ,   MAX(InitialAmount) InitialAmount
    ,   SUM(Addition) Addition
    ,   ABS(SUM(Cancellation)) Cancellation
    FROM (
    SELECT 
        Code
    ,   CASE WHEN rn = cnt THEN SaleOrderDate END SaleOrderDate
    ,   CASE WHEN rn = cnt THEN Quantity END Quantity
    ,   InitialAmount
    ,   CASE WHEN Diff > 0 THEN Diff ELSE 0 END Addition
    ,   CASE WHEN Diff < 0 THEN Diff ELSE 0 END Cancellation
    FROM (
    SELECT *
    ,   CASE WHEN TransactionNo IS NULL THEN TotalAmount END InitialAmount
    ,   LEAD(TotalAmount) OVER(PARTITION BY Code ORDER BY TransactionNo)  nxtPrice
    ,   LEAD(TotalAmount) OVER(PARTITION BY Code ORDER BY TransactionNo) - TotalAmount Diff
    ,   COUNT(*) OVER(PARTITION BY Code) cnt 
    ,   ROW_NUMBER() OVER(PARTITION BY Code ORDER BY SaleOrderDate) rn 
    FROM SaleOrder 
    ) D 
    ) C 
    GROUP BY 
        Code
    

    【讨论】:

      猜你喜欢
      • 2023-02-15
      • 2013-08-12
      • 1970-01-01
      • 2016-04-20
      • 1970-01-01
      • 2019-11-28
      • 2019-02-07
      • 1970-01-01
      • 2022-08-09
      相关资源
      最近更新 更多