J'ai une table comme celle-ci:
rowInt Value
2 23
3 45
17 10
9 0
....
Les valeurs de la colonne rowInt sont des entiers, mais pas dans une séquence avec le même incrément. Je peux utiliser le SQL suivant pour lister les valeurs par rowInt:
SELECT * FROM myTable ORDER BY rowInt;
Cela listera les valeurs par rowInt. Comment obtenir la différence de valeur entre deux lignes avec le résultat suivant:
rowInt Value Diff
2 23 22 --45-23
3 45 -35 --10-45
9 0 -45 --0-45
17 10 10 -- 10-0
....
La table est en SQL 2005 (Miscrosoft)
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)
EDIT: En y réfléchissant, l’utilisation d’une sous-requête dans la sélection (la réponse d’Ala Quassnoi) peut être plus efficace. J'essayerais différentes versions et examinerais les plans d'exécution pour voir laquelle fonctionnerait le mieux avec la taille de l'ensemble de données que vous avez ...
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
Si vous voulez vraiment être sûr des ordres, utilisez "Row_Number ()" et comparez l'enregistrement suivant de l'enregistrement en cours (examinez de près la clause "on")
T1.ID + 1 = T2.ID
Vous joignez essentiellement la ligne suivante à la ligne actuelle, sans spécifier "min" ni "top". Si vous avez un petit nombre d'enregistrements, d'autres solutions de "Dems" ou "Quassanoi" fonctionneront bien.
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
SQL Server 2012 et versions ultérieures prennent en charge LAG / LEAD des fonctions permettant d’accéder à la ligne précédente ou suivante. SQL Server 2005 ne prend pas cela en charge (dans SQL2005, vous avez besoin d'une jointure ou de quelque chose d'autre).
Un exemple SQL 2012 sur ces données
/* 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
LEAD (valeur) renverra la valeur de la ligne suivante par rapport à l'ordre donné dans la clause "over".
SQL Server prend-il en charge les fonctions d'analyse?
select rowint,
value,
value - lag(value) over (order by rowint) diff
from myTable
order by rowint
/
Requête pour trouver la différence de date entre 2 lignes d'une seule colonne
SELECT
Column name,
DATEDIFF(
(SELECT MAX(date) FROM table name WHERE Column name < b. Column name),
Column name) AS days_since_last
FROM table name AS b
select t1.rowInt,t1.Value,t2.Value-t1.Value as diff
from (select * from myTable) as t1,
(select * from myTable where rowInt!=1
union all select top 1 rowInt=COUNT(*)+1,Value=0 from myTable) as t2
where t1.rowInt=t2.rowInt-1