【问题标题】:sql compute difference between 2 rowssql计算2行之间的差异
【发布时间】:2014-12-16 14:23:26
【问题描述】:

我正在寻找一种方法来比较同一张表中 2 行之间的差异。从我在这里找到的 (How to get difference between two rows for a column field?) 来看,这几乎就是我想要的。我已经完成了以下代码:

create table #tmpTest
(
    id_fund int null,
    id_ShareType int null,
    ValueDate datetime null,
    VarNAV float null,
    FundPerf float null,
)

insert into #tmpTest(id_fund, id_ShareType, ValueDate, VarNAV)
values(1,1,'20140101',100)
insert into #tmpTest(id_fund, id_ShareType, ValueDate, VarNAV) 
values(1,1,'20140102',20)

update #tmpTest
set hrc.FundPerf = (isnull(hrn.VarNAV, 0) - hrc.VarNAV)/hrc.VarNAV
from #tmpTest hrc 
left join #tmpTest hrn on hrn.ValueDate = (select min(ValueDate) from #tmpTest where ValueDate > hrc.ValueDate)
and hrc.id_fund = hrn.id_fund and hrc.id_ShareType = hrn.id_ShareType 

我的问题是我计算的结果从第 1 行而不是第 2 行开始。

我得到的结果如下:

id_fund id_ShareType ValueDate           VarNAV                       FundPerf                     
------- ------------ ------------------- ------- -----------------------------
      1            1 2014-01-01 00:00:00     100                          -0.8
      1            1 2014-01-02 00:00:00      20                            -1

而我希望它是这样的:

id_fund id_ShareType ValueDate           VarNAV                       FundPerf                     
------- ------------ ------------------- ------- -----------------------------
      1            1 2014-01-01 00:00:00     100                            -1
      1            1 2014-01-02 00:00:00      20                          -0.8

我的方法有什么问题?

【问题讨论】:

  • 为什么不能使用LAGLEAD函数?

标签: sql sap-ase


【解决方案1】:

您并未将最低限额限制为相同的基金和股票类型。

update #tmpTest
    set hrc.FundPerf = (isnull(hrn.VarNAV, 0) - hrc.VarNAV)/hrc.VarNAV
    from #tmpTest hrc left join
         #tmpTest hrn
         on hrn.ValueDate = (select min(ValueDate)
                             from #tmpTest tt
                             where tt.ValueDate > hrc.ValueDate and
                                   hrc.id_fund = tt.id_fund and hrc.id_ShareType = tt.id_ShareType 
                            ) and
           hrc.id_fund = hrn.id_fund and hrc.id_ShareType = hrn.id_ShareType ;

【讨论】:

    【解决方案2】:

    试试这个:

    update hrn
    set FundPerf = (isnull(hrn.VarNAV, 0) - hrc.VarNAV)/hrc.VarNAV
    from #tmpTest hrc 
    left join #tmpTest hrn on hrn.ValueDate = (select min(ValueDate) from #tmpTest where ValueDate > hrc.ValueDate)
    and hrc.id_fund = hrn.id_fund and hrc.id_ShareType = hrn.id_ShareType 
    

    【讨论】:

    • 另外,按照@Gordon Linoff 的建议限制最低资金和股份类型
    • 确实你是对的:我应该限制。不过,这并不能解决我的问题。
    • 确实如此。如果您更新 hrn 而不是 hrc,则返回与日期一致(第一天的性能为 NULL)。
    【解决方案3】:

    您好,您可以使用 CTE(通用表表达式)实现此目的

    create table #tmpTest
    (
        id_fund int null,
        id_ShareType int null,
        ValueDate datetime null,
        VarNAV float null,
        FundPerf float null,
    )
    
    insert into #tmpTest(id_fund, id_ShareType, ValueDate, VarNAV)
    values(1,1,'20140101',100)
    insert into #tmpTest(id_fund, id_ShareType, ValueDate, VarNAV) 
    values(1,1,'20140102',20)
    
    ;With tbl as
    

    ( Select Row_Number() OVER (Order by T.ValueDate) as RowNumber,* From #tmpTest T )SELECT Cur.*,(ISNULL(Cur.VarNAV,0) - ISNULL(Prv.VarNAV,0))/Prv.VarNAV as [Col Name] FROM tbl Cur LEFT OUTER JOIN tbl Prv ON Cur.RowNumber = Prv.RowNumber+1 ORDER BY Cur.ValueDate

    【讨论】:

    • 突出显示您的代码并按 Ctrl+K 将对其进行格式化,使其更易于阅读 - 请参阅 how to format here
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-08
    • 1970-01-01
    • 1970-01-01
    • 2014-07-21
    • 1970-01-01
    • 2015-03-14
    相关资源
    最近更新 更多