2010-10-13 13 views
0

Table a 2 Col.: [nr] et [diff]champ SQL = autre domaine moins une autre ligne

diff est vide (jusqu'à présent - besoin de remplir)

nr a chiffres:

1 
2 
45 
677 
43523452 

sur la colonne diff i besoin d'ajouter les différences entre les paires

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

donc en gros quelque chose comme:

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

mais je ne veux pas utiliser la prochaine chercher, parce que c'est pas cool, et il est lent (100.000 dossiers)

comment puis-je faire avec une mise à jour?

+0

Ne serait-il préférable de calculer la différence sur la demande au lieu de persister? Que ferez-vous lorsque la valeur dans l'une des rangées change? Vos différences seront alors fausses. –

Répondre

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

NB: Si vous avez peut-être lié les valeurs «nr» vous pouvez utiliser 'ROW_NUMBER() OVER (ORDER BY nr, YourPrimaryKey)' pour rendre le résultat de cette expression déterministe. –

-1

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 

Ceci est en supposant que vous n'avez une ancienne ligne pour nr vieux dans le tableau. sinon le sous-requête retournera plus d'une valeur

+0

tout est INT, ce qui est nrold? – Ash

+0

@swoosh - Je suppose que nrold est une autre colonne dans la même table. ou laissez-moi savoir où vous avez stocké nrold –

+0

nr vieux est la même colonne nr ... il est juste dans une rangée différente ... (la ligne précédente en fait) – Ash

0

Jetez un oeil à quelque chose comme ceci (exemple complet)

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