【问题标题】:Running total with maximum limit运行总计与最大限制
【发布时间】:2015-06-14 11:53:04
【问题描述】:

我有一个简单的问题,但我很难解决。 我想总结一个特定的列,直到它达到限制并自行重置。 (SQL 2012)

假设限制是 50

 - List item
 - Value    Total
 - 10        10
 - 20        30
 - 30        60
 - 40        50   (60-limit) + the current row value
 - 2         2
 - 3         5
 - 10        15
 - 25        40
 - 15        55
 - 5         10 (55-limit) + the current row value

非常感谢。

【问题讨论】:

  • 您可以使用触发器,但我不建议使用诸如编写触发器的最佳方法是根本不编写触发器。您可以创建存储过程并在需要在表中插入行并在那里实现逻辑的任何地方使用它。

标签: sql sql-server sum cumulative-sum


【解决方案1】:
create table running_totals
(
    id  int identity(1,1),
    val int

)

insert into     running_totals

select 1    union all
select 20   union all
select 10   union all
select 30   union all
select 50   union all
select 10   union all
select 11   union all
select 22   union all
select 40   union all
select 60   union all
select 20   union all
select 10   union all
select 15

declare cur_run_tot cursor for select id,val from running_totals order by id asc
declare @id int ,@val int,@runtot int
open cur_run_tot
create table #RunTot
(
    id int,val int, runtot int
)

fetch next from cur_run_tot into @id,@val

while @@FETCH_STATUS = 0
begin 


    if @runtot is null or @runtot+@val > 50 
        set @runtot = @val
    else 
        set @runtot = @runtot+ @val

    insert into #RunTot
    select @id,@val,@runtot

    fetch next from cur_run_tot into @id,@val   
end

select id as ID, val as Current_Value, runtot as Running_Total from #RunTot

drop table #RunTot
deallocate cur_run_tot

【讨论】:

    【解决方案2】:

    如果您有 SQL Server 2012 或更高版本,应该这样做:

    DECLARE @Table TABLE (Id INT, ListItem INT);
    INSERT INTO @Table VALUES (1, 10);
    INSERT INTO @Table VALUES (2, 20);
    INSERT INTO @Table VALUES (3, 30);
    INSERT INTO @Table VALUES (4, 40);
    INSERT INTO @Table VALUES (5, 2);
    INSERT INTO @Table VALUES (6, 3);
    INSERT INTO @Table VALUES (7, 10);
    INSERT INTO @Table VALUES (8, 25);
    INSERT INTO @Table VALUES (9, 15);
    INSERT INTO @Table VALUES (10, 5);
    WITH RunningTotal AS (
    SELECT Id, ListItem, SUM(ListItem) OVER (ORDER BY Id) % 50 AS RT FROM @Table)
    SELECT
        rt.Id,
        rt.ListItem,
        CASE WHEN rt.RT < rt2.RT THEN rt.RT + 50 ELSE rt.RT END AS RunningTotal
    FROM
        RunningTotal rt
        LEFT JOIN RunningTotal rt2 ON rt2.Id = rt.Id - 1
    ORDER BY
        rt.Id;
    

    棘手的一点是允许数字溢出 50 一次,否则这将是微不足道的。

    结果是:

    Id  LI  RunningTotal
    1   10  10
    2   20  30
    3   30  60
    4   40  50
    5   2   2
    6   3   5
    7   10  15
    8   25  40
    9   15  55
    10  5   10
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-06
      相关资源
      最近更新 更多