Comparaison/calcul ligne par ligne dans une même colonne d'une même table

Résolu
nordine001 Messages postés 2 Date d'inscription jeudi 15 mai 2003 Statut Membre Dernière intervention 17 août 2009 - 13 août 2009 à 10:17
nivsql Messages postés 159 Date d'inscription lundi 22 juin 2009 Statut Membre Dernière intervention 14 décembre 2010 - 17 août 2009 à 10:21
Bonjour,

Afin de savoir si un service fonctionne, chaque action est enregistrée dans une table. Cette dernière n'a pas d'id autoincrémenté.

Pour chaque entrée, j'ai la date dans ce format datetime avec d'autres valeurs.
Le but est de m'assurer qu'entre 2 enregistrements (2 lignes consécutives) il ne s'est pas écoulé plus de ...
Une autre vision serait de récupérer le temps écoulé entre 2 enregistrements.

Exemple avec des valeurs.

Appelons la table "statitique" et la colonne "temps_synchro"

1° Je dois effectuer un select de "temps_synchro" avec un "order by" sur ce champ pour m'assurer que tous les temps sont croissants ou décroissants

L1 01-01-2009 08:05:32:000
L2 01-01-2009 08:05:35:000
L3 01-01-2009 08:05:37:000
L4 01-01-2009 08:06:27:000
...

2° Le but est de récupérer ceci par exemple

00:00:03:000 -->(L2-L1)
00:00:02:000 -->(L3-L2)
00:00:50:000 -->(L4-L3)
...

Pour info la table contient des centaines de millers de ligne

J'ai essayé d'utiliser le row_number(), count, ... mais pas moyen de trouver la solution. Je me suis orienter à défaut vers une comparairon des ligne pair et impair mais c'est incorrect.
Je ne vois pas comment effectuer une boucle dans sql pour effectuer cette tâche.

Je vois cela une boucle itérative avec 3 valeurs LigneA et LigneB et resultat

Dans la boucle, on effectue LigneA+i-LigneB+i=resultat (Qui m'intéresse )
i étant l'incrément allant de i=0 jusque i= count de toutes les lignes avec un pas de 1

On initialise ligneA comme étant la ligne2 et LigneB comme ligne1 et ensuite il faut incrémenter de i+1 ou i++
Donc au 1er passage j'ai bien Ligne2-ligne1
Ensuite ligne3-ligne2
...

Il faut également afficher le résultat de chaque étape forcément. Enfin dans ma tête c'est clair mais j'arrive pas à restranscrire.

J'ai lu pas mal de chose concernant le "cursor" mais je ne connais pas du tout son mode de fonctionne. J'ai essayé certaine chose mais je n'arrive pas à l'appliquer à mon cas. Je place ma question dans "requêtes" même s'il est probable qu'on aboutisse à des procédures stockées.

Merci d'avance pour votre aide, vos remarques, idées,...





Nordine001

4 réponses

nivsql Messages postés 159 Date d'inscription lundi 22 juin 2009 Statut Membre Dernière intervention 14 décembre 2010 1
14 août 2009 à 12:26
J'ai trouver une solution a ton probleme.

Contexte : J'ai créé une table MyDateChrono composé uniquement d'un champ date que j'ai alimenté via la fonction GETDATE() repeter plusieurs fois.

Voila ce que je te propose comme solution :


WITH MyChrono (Mychron, chron_id) as (
select Mydate, ROW_NUMBER() OVER(ORDER BY Mydate DESC) from MydateChrono
)
SELECT a.Mychron - b.Mychron
from MyChrono a
join MyChrono b On a.chron_id = b.chron_id - 1
1
nordine001 Messages postés 2 Date d'inscription jeudi 15 mai 2003 Statut Membre Dernière intervention 17 août 2009 1
17 août 2009 à 08:55
Merci pour la réponse rapide.

De mon côté, j'ai effectué ceci :

declare @V1 datetime
declare @V2 datetime
declare @V datetime
declare @R int
DECLARE @T TABLE (Elapse_time datetime)


set @V= 0
set @R= 0

WHILE @R < (select count (synchrodate) AS TEST from T3)

begin
set @V1= (select synchrodate
from (select synchrodate,ROW_NUMBER() OVER(ORDER BY synchrodate ASC) AS rank from t3) AS P where rank = @R+1)
set @V2= (select synchrodate
from (select synchrodate,ROW_NUMBER() OVER(ORDER BY synchrodate ASC) AS rank from t3) AS P where rank = @R+2)

INSERT INTO @T VALUES (@V)
SET @R = @R + 1
SET @V= @V2 - @V1
end

select * from @T

Je vais également tester ta solution et prendrai la plus rapide des 2.

Encore merci.
1
nivsql Messages postés 159 Date d'inscription lundi 22 juin 2009 Statut Membre Dernière intervention 14 décembre 2010 1
14 août 2009 à 12:28
Il vas de soit que si ta propre table possede une Clé primaire de type autoincrément (colonne IDENTITY) et qu'elle respecte l'ordre voulu pour tes date tu peut directement faire l'autojointure sur ta clé primaire au lieu de l'émuler comme je l'ai fait via ROW_NUMBER dans une CTE.
0
nivsql Messages postés 159 Date d'inscription lundi 22 juin 2009 Statut Membre Dernière intervention 14 décembre 2010 1
17 août 2009 à 10:21
J'ai bien peur que ta solution soit totalement contre performante au fur et a mesure de l'augmentation du volume.

Imagine : pour chaque tour dans ta boucle tu lis INTEGRALEMENT ta table 3 FOIS ! Convertis ca en Ko de lecture mémoire pour un certain nombre de lignes et tu verra le probleme (imagine une table de 1 Mo pour 100 ligne, tu lira quasi 300 Mo de données mémoire alors que finalement tu n'a qu'un 1Mo de données).
0
Rejoignez-nous