1

假设我有表,这些是它的示例行

ChangeID    Change
   1         102
   2         105
   3         107
   4         110

变化公式为

(CurrentRowChange - PreviousRowChange) / PreviousRowChange

因此:

  • 第一行应该是0
  • 第二行应该是(105 - 102) / 102

等等。如何在 SQL 中高效地编写此公式?

我知道我可以编写一个标量函数,然后执行 RowNumber 和 order By 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 回答