views:

33

answers:

3

Table has 2 cols: [nr] and [diff]

diff is empty (so far - need to fill)

nr has numbers:

 1
 2
 45
 677
 43523452

on the diff column i need to add the differences between pairs

 1 | 0
 2 | 1
 45 | 43
 677 | 632
 43523452 | 43522775

so basically something like :

 update tbl set diff = @nr - @nrold where nr = @nr

but i don't want to use fetch next, because it's not cool, and it's slow (100.000) records

how can I do that with one update?

A: 

try this -

update tablename
set diff = cast(nr as INT) - cast((select nr from tablename where diff is not null and nr = a.nr) as INT)
from tablename a
where diff is null

This is assuming you only have one older row for nr old in the table. else the subquery will return more than one value

Sachin Shanbhag
everything is INT, what is nrold ?
Swoosh
@swoosh - I am assuming nrold is another column in same table. or let me know where do you have nrold stored
Sachin Shanbhag
nr old is the same nr column ... it's just in a different row ... (the previous row actually)
Swoosh
@Swoosh - So only one older version of nr old will be available all the time right? because you need to update only when diff is null I assume
Sachin Shanbhag
@Swoosh - Lame way to do this, but updated my answer, check if this helps you
Sachin Shanbhag
this is leaving null everywhere
Swoosh
A: 
CREATE TABLE #T(nr INT,diff INT)

INSERT INTO #T (nr) SELECT 1 
              UNION SELECT 2 
              UNION SELECT 45 
              UNION SELECT 677 
              UNION SELECT 43523452

;WITH cte AS
(
SELECT nr,diff, ROW_NUMBER() OVER (ORDER BY nr) RN
FROM #T
)
UPDATE c1
SET diff = ISNULL(c1.nr - c2.nr,0)
FROM cte c1
LEFT OUTER JOIN cte c2 ON c2.RN+1= c1.RN

SELECT nr,diff FROM #T

DROP TABLE #T
Martin Smith
NB: If you might have tied `nr` values you might want to use `ROW_NUMBER() OVER (ORDER BY nr, YourPrimaryKey)` to make the result of that expression deterministic.
Martin Smith
A: 

Have a look at something like this (full example)

DECLARE @Table TABLE(
        nr INT,
        diff INT
)

INSERT INTO @Table (nr) SELECT 1 UNION ALL
SELECT 2  UNION ALL
SELECT 45  UNION ALL
SELECT 677  UNION ALL
SELECT 43523452 

;WITH Vals AS (
        SELECT  nr,
                diff,
                ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) xID
        FROM    @Table
)
UPDATE  c
SET     diff = c.nr - ISNULL(p.nr, 0)
FROM    Vals c LEFT JOIN
        Vals p  ON  c.xID = p.xID + 1


SELECT  *
FROM    @Table
astander