【问题标题】:How do perform a "customized" running total in SQL Server?如何在 SQL Server 中执行“自定义”运行总计?
【发布时间】:2017-08-23 08:11:01
【问题描述】:

我有一个临时表,我已经填充了一个运行总计。我使用了 SQL Server 窗口函数。我的临时表中的数据格式如下:

|Day  | Sku  Nbr | CMQTY  | 
| 1   |  f45     |   0    |
| 2   |  f45     |   2    | 
| 3   |  f45     |   0    | 
| 4   |  f45     |   7    | 
| 5   |  f45     |   0    | 
| 6   |  f45     |   0    | 
| 7   |  f45     |   0    | 
| 8   |  f45     |   13   | 
| 9   |  f45     |  15    | 
| 10  |  f45     |  21    |

我想对数据进行操作,使其显示如下:

|Day| Sku Nbr | CMQTY | 
| 1 |  f45    | 0     | 
| 2 |  f45    | 2     | 
| 3 |  f45    | 2     | 
| 4 |  f45    | 7     | 
| 5   |  f45  |   7   | 
| 6   |  f45  |   7   | 
| 7   |  f45  |   7   | 
| 8   |  f45  |   13  | 
| 9   |  f45  |  15   | 
| 10  |  f45  |  21   |

我尝试使用延迟函数,但是当我连续多天使用 0 CMQTY 时会出现问题。我也尝试过使用 CASE WHEN 逻辑但失败了。

【问题讨论】:

  • 第4行保留CMQTY为7的逻辑是什么?
  • 保留 CMQTY 为 7 是没有逻辑的。那是原始值。天数为 1 到 31,CMQTY 将为 0 或截至当天的运行总数。如果这不能回答你的问题,请告诉我。我的目标是当 CMQTY 之前的值不等于 0 时从 0 中删除它们。
  • 仍然不清楚您的要求...您能提供更多行作为示例吗?
  • 我添加了更多记录以供理解。顶部显示我所拥有的。底部显示我需要的内容。
  • 下面的查询给出了你的输出...

标签: tsql reporting-services ssms ssrs-2012


【解决方案1】:

你可以使用如下的row_number

;with cte as (
select *, sm = sum(case when cmqty>0 then 1 else 0 end) over (order by [day]) from #yoursum
)
select *, sum(cmqty) over(partition by sm order by [day]) from cte

你的表结构

create table #yoursum ([day] int, sku_nbr varchar(10), CMQTY int)

insert into #yoursum 
([Day]  , Sku_Nbr , CMQTY  )  values 
 ( 1   ,'f45',   0  )
,( 2   ,'f45',   2  )
,( 3   ,'f45',   0  )
,( 4   ,'f45',   7  )
,( 5   ,'f45',   0  )
,( 6   ,'f45',   0  )
,( 7   ,'f45',   0  )
,( 8   ,'f45',   13 )
,( 9   ,'f45',  15  )
,( 10  ,'f45',  21  )

【讨论】:

    【解决方案2】:

    为了好玩,另一种方法。首先是一些示例数据:

    IF OBJECT_ID('tempdb..#t1') IS NOT NULL DROP TABLE #t1;
    
    CREATE TABLE #t1
    (
      [day]     int        NOT NULL,
      [Sku Nbr] varchar(5) NOT NULL, 
      CMQTY     int        NOT NULL,
      CONSTRAINT pk_t1 PRIMARY KEY CLUSTERED([day] ASC)
    );
    
    INSERT #t1 VALUES
    (1 , 'f45', 0),
    (2 , 'f45', 2),
    (3 , 'f45', 0),
    (4 , 'f45', 7),
    (5 , 'f45', 0),
    (6 , 'f45', 0),
    (7 , 'f45', 0),
    (8 , 'f45', 13), 
    (9 , 'f45', 15), 
    (10, 'f45', 21);
    

    以及解决方案:

    DECLARE @RunningTotal int = 0;
    
    UPDATE #t1
    SET @RunningTotal = CMQTY = IIF(CMQTY = 0, @RunningTotal, CMQTY)
    FROM #t1 WITH (TABLOCKX)
    OPTION (MAXDOP 1);
    

    结果:

    day  Sku Nbr CMQTY
    ---- ------- ------
    1    f45     0
    2    f45     2
    3    f45     2
    4    f45     7
    5    f45     7
    6    f45     7
    7    f45     7
    8    f45     13
    9    f45     15
    10   f45     21
    

    这种方法被称为本地可更新变量或 Quirky Update。你可以在这里阅读更多信息:http://www.sqlservercentral.com/articles/T-SQL/68467/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-26
      • 1970-01-01
      • 2018-01-14
      • 1970-01-01
      • 2021-12-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多