1

私がテーブルを持っていて、これらがそのサンプル行であるとしましょう

ChangeID    Change
   1         102
   2         105
   3         107
   4         110

変更式は

(CurrentRowChange - PreviousRowChange) / PreviousRowChange

したがって:

  • 1行目は0
  • 2行目は(105 - 102) / 102

等々。この式をSQLで効率的に書くにはどうすればよいですか?

スカラー関数を記述してから、RowNumberを実行してChangeIDで順序付けし、行番号のChange値をフェッチしてから、現在の行番号-1を見つけて、その行のChange値をフェッチして除算を実行できることを知っています。

これを達成するためのより良い方法はありますか?

4

4 に答える 4

4

が削除CHANGEID可能であり、IDENTITY.

WITH changeList
AS
(
    SELECT ChangeID, [Change],
           (ROW_NUMBER() OVER (ORDER BY ChangeID ASC)) -1 AS rn
    FROM   TableName
),
normalList
AS
(
    SELECT ChangeID, [Change],
           (ROW_NUMBER() OVER (ORDER BY ChangeID ASC)) AS rn
    FROM   TableName
)
SELECT a.ChangeID, a.[Change], 
       COALESCE((a.Change - b.change) / (b.change * 1.0),0) result
FROM   changeList a
       LEFT JOIN normalList b
          ON a.rn = b.rn
于 2013-02-03T12:21:21.753 に答える
4
select  cur.*
,       case
        when prev.ChangeId is null then 0
        else 1.0 * (cur.Change - prev.Change) / prev.Change
        end
from    Table1 cur
left join
        Table1 prev
on      cur.ChangeId = prev.ChangeId + 1

SQL フィドルの例。

于 2013-02-03T12:23:18.343 に答える
0

サンプルでは ChangeID は連続していますが、常にそうであるとは思いません。だから私はこのようなことをします:

 with RankedIDs as
 select ChangeID
 , Change
 , rank() over
 (partition by ChangeID order by ChangeId) rank
 where something maybe ;

 select case
 when r1.rank = 1 then 0
 else (r1.change - r2.change) / r2.change
 end SomeName
 from RankedIds r1 join RankedIds r2 on r1.rank = r2.rank + 1

それが基本的な考え方です。ゼロ除算保護を追加することをお勧めします

于 2013-02-03T12:29:42.010 に答える
0
select T1.ChangeID,
       (1.0 * T1.Change / T2.Change) - 1 as Result
from TableName as T1
  outer apply (
              select top(1) T.Change
              from TableName as T
              where T.ChangeID < T1.ChangeID
              order by T.ChangeID desc
              ) as T2
于 2013-02-03T17:14:52.863 に答える