Précédent   Forum des professionnels en informatique > Bases de données > MySQL > SQL Procédural
SQL Procédural Forum d'entraide sur les triggers, les procédures stockées et les fonctions en MySQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 12/09/2011, 23h04   #1
Invité de passage
 
Inscription : janvier 2005
Messages : 12
Détails du profil
Informations forums :
Inscription : janvier 2005
Messages : 12
Points : 3
Points : 3
Par défaut Moyenne mobile (ou glissante)

Bonjour

Avec l'actualité, j'ai voulu me pencher un peu sur la bourse et manipuler quelques indicateurs.

Pour commencer simple, j'ai regardé comment calculer une moyenne mobile (ou glissante). Il s'agit en fait pour un enregistrement donné de faire la moyenne des x dernières valeurs, ici 3.

Code :
1
2
3
4
5
6
source 	date 		value 	mm(3)
GLE 	09/09/2011	17,440	18,777
GLE 	08/09/2011	19,510	19,270
GLE 	07/09/2011	19,380	19,517
GLE 	06/09/2011	18,920	0,000
GLE 	05/09/2011	20,250	0,000
Pour cela, j'aimerais créer une procédure qui sera déclenché à l'insertion (ou mise à jour) d'un enregistrement.
Dois-je passer par un curseur qui sommera et divisera par le nombre de valeur ? Une requête imbriquée ?

Pourriez-vous m'orienter vers une solution car j'avoue débuter dans les procédures stockées.

Merci d'avance et bonne nuit (?)
Poppy est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/09/2011, 00h13   #2
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 11 029
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur d'études en informatique
Secteur : Enseignement

Informations forums :
Inscription : août 2006
Messages : 11 029
Points : 18 327
Points : 18 327
Envoyer un message via MSN à CinePhil
Ça doit être faisable dans un trigger.

1) Le trigger doit vérifier si la moyenne mobile est calculabe
Le résultat de la requête ci-dessous doit être supérieur à 1 ; il doit y avoir déjà au moins deux lignes pour GLE + celle qu'on est en train d'insérer pour calculer la MM3.
Code :
1
2
3
SELECT COUNT(*)
FROM cours
WHERE source = 'GLE'
2) Faire la somme des cours des deux lignes les plus récentes + le cours qu'on insère
Code :
1
2
3
4
5
SELECT SUM(value) + NEW.value
FROM cours
WHERE source = 'GLE'
ORDER BY`date` DESC
LIMIT 2
3) Affecter le résultat de la requête ci-dessus à NEW.mm3

Bon courage.
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/09/2011, 11h28   #3
Invité de passage
 
Inscription : janvier 2005
Messages : 12
Détails du profil
Informations forums :
Inscription : janvier 2005
Messages : 12
Points : 3
Points : 3
Merci CinePhil

Je poserai ma solution quand je l'aurai trouvée.

Bonne journée.
Poppy est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/09/2011, 14h51   #4
Invité de passage
 
Inscription : janvier 2005
Messages : 12
Détails du profil
Informations forums :
Inscription : janvier 2005
Messages : 12
Points : 3
Points : 3
Bonjour

Voici un premier jet. J'ai donc 2 nouvelles questions.

Dans ce cas (légèrement différence du premier énoncé), je veux calculer plusieurs moyennes mobiles (mm10, mm20, mm30 et mm50) et donc il y aura autant de champs dans ma table cible (qui s'appelle 'historical_quotes' et la valeur est stockée dans le champ 'close' - pour la valeur de clôture)
  • Mon premier problème est que tous les résultats retournés sont des entiers. Comment y remédier ?
  • Comment tester avec la valeur NEW.value tant que le trigger n'est pas en place ?

Code :
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
CREATE PROCEDURE `compt`(IN symbol VARCHAR(5), IN fromDate DATE)
BEGIN
DECLARE n INT;
DECLARE tmp FLOAT DEFAULT 0;
DECLARE val FLOAT;
DECLARE i INT DEFAULT 0;
DECLARE curseur CURSOR FOR SELECT `close` FROM historical_quotes WHERE `source` = symbol AND date <= fromDate LIMIT 50;
 
SELECT count(*) INTO n FROM historical_quotes WHERE `source` = symbol AND date <= fromDate;
 
IF n = 0 THEN
    SELECT '= 0';
 
ELSE
    OPEN curseur;
 
    WHILE i < 50 DO
        SET i := i + 1;
        FETCH curseur INTO val;
        SET tmp := tmp + val;
 
        IF i = 10 THEN
            SELECT 'i=10' | tmp / i;
        END IF;
 
        IF i = 20 THEN
            SELECT 'i=20' | tmp / i;
        END IF;
 
        IF i = 30 THEN
            SELECT 'i=30' | tmp / i;
        END IF;
 
        IF i = 50 THEN
            SELECT 'i=50' | tmp / i;
        END IF;
 
    END WHILE;
 
    CLOSE curseur;
END IF;
 
END
Merci pour votre aide
Poppy est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/09/2011, 14h52   #5
Invité de passage
 
Inscription : janvier 2005
Messages : 12
Détails du profil
Informations forums :
Inscription : janvier 2005
Messages : 12
Points : 3
Points : 3
Le résultat :

Code :
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
mysql> call compt('GLE','2011-01-01');
+------------------+
| 'i=10' | tmp / i |
+------------------+
|               57 |
+------------------+
1 row IN SET (0.01 sec)
 
+------------------+
| 'i=20' | tmp / i |
+------------------+
|               56 |
+------------------+
1 row IN SET (0.01 sec)
 
+------------------+
| 'i=30' | tmp / i |
+------------------+
|               54 |
+------------------+
1 row IN SET (0.01 sec)
 
+------------------+
| 'i=50' | tmp / i |
+------------------+
|               52 |
+------------------+
1 row IN SET (0.01 sec)
 
Query OK, 0 rows affected, 4 warnings (0.01 sec)
Poppy est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 00h09.


 
 
 
 
Partenaires

Hébergement Web