C'est ce que j'ai fais.
J'ai 245000 lignes dans ma table et j'ai calculé la moyenne et l'écart type de ma colonne.
Alors je sais pas...
Je vais implémenter l'algo de souviron34 ( merci au passage :D)
jko
Version imprimable
Voici la validation du code de souviron34.
La procédure en PlSql
Nombre de valeurs de lignes pour valeur de stat 0: 112571Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96 Create Or Replace Procedure NormalyzeValues (pIdStat Number) as Cursor GetCrs is Select idc, rownum From (Select idc from CrsSimu order by idc); Cursor GetPt (pIdc Number) is Select nvl (valeur,0),numpartant from AllStats where idc = pIdc and idstat = pIdStat; Type TVal IS TABLE OF Number INDEX BY BINARY_INTEGER; TabMax TVal; TabMin TVal; lIdc Number; lNum Number; lVal Number; lPt Number; lMin Number := 1000000; lMax Number := 0; lRes Number; Begin OPEN GetCrs; LOOP FETCH GetCrs INTO lIdc,lNum; EXIT WHEN GetCrs%NOTFOUND; -- Initialisation de la position TabMax(lNum) := 0; TabMin(lNum) := 1000000; OPEN GetPt (lIdc); LOOP FETCH GetPt INTO lVal,lPt; EXIT WHEN GetPt%NOTFOUND; --si valeur(ivaleur, icourse) > max -- max = valeur(ivaleur, icourse) --fin si if lVal > lMax Then lMax := lVal; End if; --si valeur(ivaleur, icourse) > tablemax(icourse) -- tablemax(icourse) = valeur(ivaleur, icourse) --fin si if lVal > TabMax(lNum) Then TabMax(lNum) := lVal; End if; --si valeur(ivaleur, icourse) < min --min = valeur(ivaleur, icourse) --fin si if lVal < lMin Then lMin := lVal; End if; --si valeur(ivaleur, icourse) < tablemin(icourse) --tablemin(icourse) = valeur(ivaleur, icourse) --fin si if lVal < TabMin(lNum) Then TabMin(lNum) := lVal; End if; End Loop; Close GetPt; End Loop; Close GetCrs; Delete from tmp where idstat = pIdStat; OPEN GetCrs; LOOP FETCH GetCrs INTO lIdc,lNum; EXIT WHEN GetCrs%NOTFOUND; if TabMax(lNum) > 0 Then OPEN GetPt (lIdc); LOOP FETCH GetPt INTO lVal, lPt; EXIT WHEN GetPt%NOTFOUND; -- Etape 2 et 3 lRes := (lVal - TabMin(lNum)) * (lMax - lMin) / (TabMax(lNum) - TabMin(lNum)) + lMin; lRes := (lRes - lMin) * 1000 / (lMax - lMin); insert into Tmp values (lidc,lPt,pIdStat,lVal,lRes); End Loop; Close GetPt; End if; commit; End Loop; Close GetCrs; End; / Show err /
exec NormalyzeValues (0)
Temps d'éxécution: 3 secondes
Résultat:
select min (oldval), min (newval), max (oldval), max (newval) from tmp;
OldMin = 0
NewMin = 0
OldMax = 19569
NewMax = 1000
Et qlq exemples
19,1 149,803922
24,7 193,72549
25 196,078431
33,1 259,607843
43,6 341,960784
46 360,784314
52,7 413,333333
66,5 521,568627
69,4 544,313725
72,4 567,843137
Ca marche !
Merci a toi!
a+
jko
De rien :D
C'était assez simple, me semblait-il..
D'ailleurs, en y regardant une 2ième fois, je pense qu'on peut passer directement à l'étape 3 sans l'étape 2. Tel que je l'avais écrit, c'était pour la compréhension.
Mais normalement avoir seulement :
devrait suffireCode:lRes := (lVal - TabMin(lNum)) * 1000 / (TabMax(lNum) - TabMin(lNum)) ;
Bonjour,
moi je sais... tu t'es trompé dans ton implémentation ;)
Si tu l'as correctement développé, tu ne peux dépasser des bornes.
Est ce que tu n'aurais pas fait le calcul de la moyenne et de l'écart type que sur la première colonne en oubliant de la refaire pour les colonnes suivantes ?