如何为列字段获取两行之间的差异?

Dav*_*.ca 55 sql t-sql sql-server sql-server-2005

我有这样一张桌子:

rowInt  Value
2       23
3       45
17      10
9       0
....
Run Code Online (Sandbox Code Playgroud)

列rowInt值是整数,但不是具有相同增量的序列.我可以使用以下sql按rowInt列出值:

SELECT * FROM myTable ORDER BY rowInt;
Run Code Online (Sandbox Code Playgroud)

这将按rowInt列出值.如何获得两行之间的Value的差异,结果如下:

rowInt   Value Diff
2        23    22    --45-23
3        45    -35   --10-45
9        0     -45   --0-45
17       10    10    -- 10-0
....
Run Code Online (Sandbox Code Playgroud)

该表在SQL 2005(Miscrosoft)中

Mat*_*lie 56

SELECT
   [current].rowInt,
   [current].Value,
   ISNULL([next].Value, 0) - [current].Value
FROM
   sourceTable       AS [current]
LEFT JOIN
   sourceTable       AS [next]
      ON [next].rowInt = (SELECT MIN(rowInt) FROM sourceTable WHERE rowInt > [current].rowInt)
Run Code Online (Sandbox Code Playgroud)

编辑:考虑一下,在select(ala Quassnoi的答案)中使用子查询可能会更有效率.我会尝试不同的版本,并查看执行计划,看看哪个在你拥有的数据集大小上表现最好...


Qua*_*noi 25

SELECT rowInt, Value,
       COALESCE(
       (
       SELECT TOP 1 Value
       FROM myTable mi
       WHERE mi.rowInt > m.rowInt
       ORDER BY
             rowInt
       ), 0) - Value AS diff
FROM  myTable m
ORDER BY
      rowInt
Run Code Online (Sandbox Code Playgroud)


小智 13

SQL Server 2012及更高版本支持LAG/LEAD函数来访问上一行或后续行.SQL Server 2005不支持此功能(在SQL2005中,您需要连接或其他内容).

有关此数据的SQL 2012示例

/* Prepare */
select * into #tmp
from
(
    select 2  as rowint,      23 as Value
    union select 3,       45
    union select 17,      10
    union select 9,       0
) x


/* The SQL 2012 query */
select rowInt, Value, LEAD(value) over (order by rowInt) - Value  
from #tmp
Run Code Online (Sandbox Code Playgroud)

LEAD(value)将返回"over"子句中相对于给定顺序的下一行的值.


dan*_*die 11

如果你真的想确定订单,请使用"Row_Number()"并比较当前记录的下一条记录(仔细查看"on"子句)

T1.ID + 1 = T2.ID
Run Code Online (Sandbox Code Playgroud)

您基本上是使用当前行加入下一行,而不指定"min"或执行"top".如果您有少量记录,"Dems"或"Quassanoi"的其他解决方案将正常工作.

with T2 as (
    select  ID = ROW_NUMBER() over (order by rowInt),
            rowInt, Value
    from    myTable
)
select  T1.RowInt, T1.Value, Diff = IsNull(T2.Value, 0) - T1.Value
from    (   SELECT  ID = ROW_NUMBER() over (order by rowInt), *
            FROM    myTable ) T1
        left join T2 on T1.ID + 1 = T2.ID
ORDER BY T1.ID
Run Code Online (Sandbox Code Playgroud)