【问题标题】:SQL Server - How to solve FIFO Cost of OHB… function, cursor,?SQL Server - 如何解决 OHB... 函数、游标的 FIFO 成本?
【发布时间】:2016-12-29 13:35:07
【问题描述】:

SQL Server 2008 R2 - 需要解决手头物品的 FIFO 成本。为此,我需要将最近收货数量的成本加到当前手头余额 (OHB) 中。

所以说我有

Item : b1234 
OHB : 5

收据:

RctNumb | Item  | QTYRct | RctCostPerItem | DATERECD
rct05   | b1234 |      1 |           1.00 | 20160822
rct04   | b1234 |      3 |           2.00 | 20160820
rct03   | b1234 |      3 |           1.25 | 20160819
rct02   | b1234 |      2 |           2.50 | 20160818
rct01   | b1234 |      8 |           2.00 | 20160810

这里我需要:(1*1.00)+(3*2.00)+(1*1.25) = CostofOHB = 8.25

我不知道如何用 SQL 解决这个问题。

【问题讨论】:

  • 为什么四个空格前缀不能保留我的空格?
  • 因为你需要在标题和下一段之间有一个空行来达到这个效果
  • 您需要的是运行总计。使用 2012,它非常简单高效。在 2008R2 中,您需要执行更复杂的 SQL,而且速度要慢得多。
  • 看看这里:sqlperformance.com/2012/07/t-sql-queries/running-totals。他对各种方法进行了一些基准测试。提供的查询是针对单个运行总计的,但它可以很容易地适应多个运行总计。根据这篇文章,你最好的选择是游标(尽管我们都试图像瘟疫一样避免它们)。当然,如果您可以切换到 2012 年,那就不费吹灰之力了
  • 谢谢@P.Kouvarakis 我会努力解决这个问题。我以前从未使用过游标。如果我让它工作,我会在这里发布我的解决方案。了解我可能会有缺陷......

标签: sql-server recursion sql-server-2008-r2 fifo with-statement


【解决方案1】:

感谢其他来源的提示,我想出了这个。 running-totals nested-cursors-w-errors 与 2012 年或以后的 over(order by) 选项相比,它非常慢。

DECLARE @FiFo TABLE
(
RctNumb | Item  | QTYRct | RctCostPerItem | DATERECD
    OHBFIFOCOST     decimal(19,5),
    OHB     decimal(19,5),
    SumRctInvcd decimal(19,5),
    QtyToCost       decimal(19,5),
    ITEM        nvarchar(65) PRIMARY KEY,
    ReportDate  [datetime2](0) 

);
 declare @ITEM as char(31)
 declare @OHB      as decimal(19,5)


 declare @outer_cursor cursor
 declare @inner_cursor cursor

 declare    @RctNumb        nvarchar(32)
 declare    @RCTITEM    as nvarchar(65) 
 declare    @QTYRct     decimal(19,5)
 declare    @SumRctInvcd    decimal(19,5)
 declare    @QtyToCost      decimal(19,5)
 declare    @RctCostPerItem     decimal(19,5)
 declare    @OHBCOST        decimal(19,5)
 declare    @OHBrem         decimal(19,5)
 declare    @rowIndex       int
 declare    @DATERECD       datetime


 declare @fetch_outer_cursor int
 declare @fetch_inner_cursor int

 set @outer_cursor  = cursor static local for 

Select 
    ITEM
    ,OHB
    from ItemMaster
    where OHB > 0 

  /*loop through top level cursor*/
  open @outer_cursor 
  fetch next from @outer_cursor into @ITEM, @OHB 
  select @fetch_outer_cursor = @@FETCH_STATUS

  while @fetch_outer_cursor = 0
  begin
     /*loop through second level cursor*/
        set @inner_cursor  = cursor static local for 
        select 
            RctNumb
            ,QTYRct
            ,RctCostPerItem
            ,ITEM
            ,DATERECD
            ,rowIndex
        from RctTbl 
        Where ITEM = @ITEM
        Order By rowIndex desc

     open @inner_cursor
     fetch next from @inner_cursor into @RctNumb, @QTYRct, @RctCostPerItem, @RCTITEM, @DATERECD, @rowIndex

     set @fetch_inner_cursor = @@FETCH_STATUS
     while @OHBrem >0  and @fetch_inner_cursor = 0
     begin

        set @OHBrem         = @OHBrem - @QTYRct
        set @QtyToCost      =  case 
                                When @SumRctInvcd + @QTYRct <= @OHB Then @QTYRct
                                else @OHB - @SumRctInvcd
                            end
        set @OHBCOST        = case 
                                When @SumRctInvcd + @QTYRct <= @OHB Then @OHBCOST + (@QtyToCost * @RctCostPerItem)
                                else @OHBCOST + (@QtyToCost * @RctCostPerItem)
                            end
        set @SumRctInvcd    = @SumRctInvcd + @QtyToCost

        fetch next from @inner_cursor into @RctNumb, @QTYRct, @RctCostPerItem, @RCTITEM, @DATERECD, @rowIndex

        set @fetch_inner_cursor = @@FETCH_STATUS
     end
     close @inner_cursor
     deallocate @inner_cursor
        INSERT @FiFo(OHBFIFOCOST, OHB,  ITEM, ReportDate, QtyToCost, SumRctInvcd)
        SELECT @OHBCOST, @OHB, @ITEM, GETDATE(), @QtyToCost, @SumRctInvcd;

     fetch next from @outer_cursor into  @ITEM, @OHB  
     set @fetch_outer_cursor = @@FETCH_STATUS


  end

  close @outer_cursor  
  deallocate @outer_cursor 
  select * from @FiFo

【讨论】:

    猜你喜欢
    • 2011-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-01
    相关资源
    最近更新 更多