SQL在条件上运行完全重置

时间:2016-12-23 02:03:27

标签: sql sql-server sql-server-2012

我有下表:

交易记录表

TransactionHistoryId    ProductCode Type    Quantity    PurchasePrice   CurrentPrice
1                       Product1    B       10          3.00            2.00
2                       Product1    B       5           7.00            2.00
3                       Product1    S       -7          7.00            2.00
4                       Product1    S       -8          3.00            3.00
5                       Product1    B       4           10.00           10.00
6                       Product1    B       5           12.00           12.00
8                       Product2    B       8           20.00           20.00

我想获得下表:

TransactionHistoryId    ProductCode Type    Quantity    PurchasePrice   QtyRunning  PriceRunning
1                       Product1    B       10          3.00            10          30.00
2                       Product1    B       5           7.00            15          65.00
3                       Product1    S       -7          7.00            8           65.00
4                       Product1    S       -8          3.00            0           0.00
5                       Product1    B       4           10.00           4           40.00
6                       Product1    B       5           12.00           9           100.00
8                       Product2    B       8           20.00           8           160.00

创建表SQL

IF OBJECT_ID('TEMPDB..#TransactionHistory') IS NOT NULL
DROP TABLE #TransactionHistory
create table #TransactionHistory
(TransactionHistoryId int, 
ProductCode varchar(10),
Type char(1),
Quantity smallint,
PurchasePrice decimal(18,2),
CurrentPrice decimal(18,2)
)
insert into #TransactionHistory
values
(1,'Product1','B',10,3.00,2.00),
(2,'Product1','B',5,7.00,2.00),
(3,'Product1','S',-7,7.00,2.00),
(4,'Product1','S',-8,3.00,3.00),
(5,'Product1','B',4,10.00,10.00),
(6,'Product1','B',5,12.00,12.00),
(8,'Product2','B',8,20.00,20.00)

规则

  1. 当运行总量为0时,PriceRunningTotal重置
  2. PriceRunningTotal仅总结Type ='B'(买入),当Type ='S'(已售出)时,保持先前的购买价格总计
  3. 请注意,有一个产品2,因此它应该拥有独立于产品1的自己的运行计数
  4. 目的

    最终找出以下内容的查询:

    Product     Quantity       AdjustedPurchasePrice
    Product1    9              $11.11
    Product2    8              $20 
    

    我使用以下SQL Server 2012查询来获取结果,但我觉得它可以做得更好:

    查询

    SELECT *,   
        PriceRunningTotalFinal = 
        SUM(CASE 
        WHEN QuantityRunningTotal = 0 THEN -1 * PriceRunningTotal
        WHEN Quantity < 0 THEN 0 ELSE PurchasePrice * Quantity END) OVER 
        (
            PARTITION BY ProductCode
            ORDER BY TransactionHistoryId ROWS UNBOUNDED PRECEDING
        )   
    FROM (
    
    SELECT TransactionHistoryId, ProductCode, Type,  Quantity, PurchasePrice,  
      QuantityRunningTotal = SUM(Quantity) OVER 
      (
        PARTITION BY ProductCode
        ORDER BY TransactionHistoryId ROWS UNBOUNDED PRECEDING
      ),  
      PriceRunningTotal = SUM(CASE WHEN Quantity < 0 THEN 0 ELSE PurchasePrice * Quantity END) OVER 
      (
        PARTITION BY ProductCode
        ORDER BY TransactionHistoryId ROWS UNBOUNDED PRECEDING
      )       
      FROM TransactionHistory
    ) AS Results1
    ORDER BY ProductCode;
    

    问题

    理想情况下,我希望在另一个查询中使用QuantityRunningTotal,但我无法嵌套窗口函数。

    任何人都知道更有效的方法来实现这一结果吗?

1 个答案:

答案 0 :(得分:3)

嗯。我想是这样的:

select th.*,
       sum(case when type = 'B' then Quantity * PurchasePrice
                else 0
           end) over (partition by grp, ProductCode order by TransactionHistoryId
                     ) as PriceRunningTotal
from (select th.*,
             sum(case when running_quantity = 0 then 1 else 0 end) over (partition by ProductCode order by TransactionHistoryId) as grp
      from (select th.*,
                   sum(quantity) over (partition by ProductCode order by TransactionHistoryId
                                      ) as running_quantity
            from TransactionHistory th
           ) th;

我不确定这是否与您的查询逻辑相同。对于此查询:

  1. 最里面的子查询计算运行数量。
  2. 中间子查询根据运行数量为0的次数计算组。
  3. 最外面的查询然后计算运行价格。