SQL Server:条件聚合;

use*_*773 11 c# sql sql-server sql-server-2012

我有一个看起来像这样的表:

  Year       Value
  -----------------
  2013      -0.0016
  2014      -0.0001
  2015       0.0025
  2016      -0.0003
  2017       0.0023
  2018       0.0002
Run Code Online (Sandbox Code Playgroud)

我需要执行一个条件聚合,从而产生一个新列.条件如下:

如果值为负,则聚合开始并且在值为正之前不会停止.然后没有什么,直到值再次为负...结果将如下所示:

  Year       Value        AggCol
  2013      -0.0016      -0.0016
  2014      -0.0001      -0.0017
  2015       0.0025       0.0008
  2016      -0.0003      -0.0003
  2017       0.0023       0.002
  2018       0.0002       0.0002
Run Code Online (Sandbox Code Playgroud)

这个udf和我一样接近:

create function dbo.fn(@cYear numeric, @rate float)
returns float
as 
begin
    declare @pYear numeric
    declare @return float

    set @pYear = @cYear - 1

    set @return = (select 
                        case 
                            when Value < 0 and @rate > 0  then null 
                            when Value < 0 then Value + @rate
                            else @rate 
                        end 
                   from Table1 
                   where [year] = @pYear)

    return @return
end
Run Code Online (Sandbox Code Playgroud)

我很乐意在c#中给出答案,如果这样会更容易但更喜欢SQL.我所做的功能的问题是我需要能够从上一行获取结果,以便在值为正时添加值.

我整晚都在这里寻找线索,没有快乐......

编辑:因此,将这些视为您的运营商应用于您的手机账单的年度CPI值...它们只会增加您的账单CPI,而不会减少它(如果CPI为负)...但如果当年的CPI为正(或总和结果为正),它们将抵消前几年的CPI负当前CPI ...

这可能会有所帮助,也可能没有帮助,但情况就是这样.

Gio*_*uri 6

DECLARE @t TABLE ( [Year] INT, Value MONEY )

INSERT  INTO @t
VALUES  ( 2013, -0.0016 ),
        ( 2014, -0.0001 ),
        ( 2015, 0.0025 ),
        ( 2016, -0.0003 ),
        ( 2017, 0.0023 ),
        ( 2018, 0.0002 )

SELECT  t1.Year ,
        t1.Value ,
        oa.AggCol
FROM    @t t1
        OUTER APPLY ( SELECT    SUM(Value) AS AggCol
                      FROM      @t t2
                      WHERE     Year <= t1.Year
                                AND Year > ( SELECT ISNULL(MAX(Year), 0)
                                             FROM   @t
                                             WHERE  Year < t1.Year AND Value > 0)
                    ) oa
Run Code Online (Sandbox Code Playgroud)

输出:

Year    Value    AggCol
2013    -0.0016  -0.0016
2014    -0.0001  -0.0017
2015    0.0025   0.0008
2016    -0.0003  -0.0003
2017    0.0023   0.002
2018    0.0002   0.0002
Run Code Online (Sandbox Code Playgroud)

这意味着:对于每一行,给出一个小于或等于当前行的值的总和,并且大于在当前行之前出现的具有正值的最大行,或者如果没有找到这样的值则从0开始.