具有选择行累积计算功能的SQL SELECT

时间:2019-04-03 22:18:52

标签: sql-server calculated-columns lag

大家好,在此先感谢您的帮助。

我被困在查询的计算列上。我想计算每个订单所需单位的商品库存量如何减少,因此我在CALCULATEDSTOCK列中有剩余的库存信息。

对于每个 ARTICLE&COLOR&SIZE 的第一次出现,CALCULATEDSTOCK是“初始”股票,而对于 ARTICLE&COLOR&SIZE相同的第二次和下一次出现。 strong> CALCULATEDSTOCK比以前需要的单位减少了,所以我得到了该行的可用库存。

请注意,STOCK始终与直接查询数据库相同。

这是我想要得到的结果:

ORDER   ARTICLE  COLOR    SIZE   STOCK   NEEDED   CALCULATEDSTOCK
-----------------------------------------------------------------
43002   1000     GREY     L      13      4        13
43002   1000     GREY     XL     20      5        20
43006   1000     GREY     XL     20      4        15 
43012   1000     GREY     XL     20      6        11
43021   1000     GREY     XL     20      2        5
43021   1000     PURPLE   M      7       2        7
43023   1000     PURPLE   L      6       3        6

找到下面我尝试过的内容,但是我无法将LAG命令应用于上一个CALCULATEDSTOCK列,因此我不能计算出超过两行...

SELECT ORDER, ARTICLE, COLOR, SIZE, STOCK, NEEDED,
CAST( CASE WHEN ARTICLE = LAG(ARTICLE) OVER (ORDER BY ARTICLE, COLOR, SIZE, ORDER)
   AND COLOR = LAG(COLOR) OVER (ORDER BY ARTICLE, COLOR, SIZE, ORDER)
   AND SIZE = LAG(SIZE) OVER (ORDER BY ARTICLE, COLOR, SIZE, ORDER)
THEN 
(lag(STOCK) OVER (ORDER BY ARTICLE, COLOR, SIZE, ORDER))
-(lag(NEEDED) OVER (ORDER BY ARTICLE, COLOR, SIZE, ORDER))

ELSE STOCK
END
AS decimal(8, 2)) AS CALCULATEDSTOCK
.....

在该示例中,有3行具有相同ARTICLE&COLOR&SIZE的ORDERS,但可能还有更多行...

非常感谢您的耐心和甜蜜的问候!

2 个答案:

答案 0 :(得分:0)

我认为您缺少PARTITION。同样,LAG很好,但是如果您只是进行某种总计,SUM加上一点计算就可以了。首先,您在源数据中需要一个ID;重复的列会将其弄乱。

with source (ORDER_id,   ARTICLE,  COLOR ,   SIZE,   STOCK,   NEEDED) as
(
select 43002,   1000   ,  'GREY  ',   'L '  ,   13   ,   4 union all 
select 43002,   1000   ,  'GREY  ',   'XL'  ,   20   ,   5 union all 
select 43006,   1000   ,  'GREY  ',   'XL'  ,   20   ,   4 union all 
select 43012,   1000   ,  'GREY  ',   'XL'  ,   20   ,   6 union all 
select 43021,   1000   ,  'GREY  ',   'XL'  ,   20   ,   2 union all 
select 43021,   1000   ,  'PURPLE',   'M '  ,   7    ,   2 union all 
select 43023,   1000   ,  'PURPLE',   'L '  ,   6    ,   3 
)
select id, order_id, article, color, size, stock, NEEDED, stock + needed - sum(needed) over (partition by ARTICLE, COLOR, SIZE order by id)
from (
    select row_number() over (order by order_id) id, ORDER_id, ARTICLE, COLOR, SIZE, STOCK, NEEDED
    from source
) source_with_id

答案 1 :(得分:0)

也许有一种更优雅的方法,但这是一个选择:

; with CTE as (select *
    , stock - sum(needed) over (partition by ARTICLE, color, size order by ORDER) as CalcNeeded
    , lead(ORDER) over (partition by ARTICLE, color, size order by ORDER) as PrevOrder
from MyTable)

select a.ORDER,
       a.ARTICLE,
       a.color,
       a.size,
       a.stock,
       a.needed,
       ISNULL(b.CalcNeeded, a.stock)
from cte a
left join cte b
on a.ARTICLE= b.ARTICLE and a.color = b.color and a.size = b.size
and a.ORDER = b.PrevOrder