2014-12-16 2 views
7

Я ищу методологию для сравнения разницы между двумя строками в одной таблице. Из того, что я нашел здесь (How to get difference between two rows for a column field?), это почти то, что я хотел. Я сделал следующий код:sql вычислить разницу между 2 строками

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 

что случилось с моим подходом?

+4

Почему вы не можете использовать 'LAG' и 'LEAD' функции? – Kermit

ответ

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 ; 
+0

Вы правы !!! Большое спасибо :) – sa6

0

Попробуйте это:

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 
+0

Также ограничьте минимальный размер фонда и разделите его, как предложено @Gordon Linoff – Russop

+0

Действительно, вы правы: я должен ограничиться. Тем не менее, это не решает мою проблему. – sa6

+0

Он делает. Если вы обновляете hrn вместо hrc, возврат выравнивается с датами (производительность за первый день равна NULL). – Russop

0

Привет Вы можете достичь этого, используя по КТР (Common Таблица Expression)

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

+0

Выделение вашего кода и нажатие Ctrl + K отформатирует его, что упростит его чтение - см. [Как отформатировать здесь] (http://meta.stackexchange.com/a/22189) – AHiggins

Смежные вопросы