Précédent   Forum des professionnels en informatique > Bases de données > Oracle > SQL
SQL Forum d'entraide sur le SQL pour Oracle
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 16/01/2012, 15h42   #1
Membre régulier
 
Inscription : septembre 2008
Messages : 85
Détails du profil
Informations forums :
Inscription : septembre 2008
Messages : 85
Points : 89
Points : 89
Par défaut Représentation formule math

Bonjour,

Je suis sous Oracle 10g et je veux :
1- représenter une formule de calcul (simple) en base
2- reconstruire la formule à partir d'une requête SQL

Pour le "1", je représente ma formule sous forme d'arbre binaire avec l'opérateur (+, -, * ou /) sur chaque noeud et une constante ou une "sous-formule" sur chaque branche.

J'ai essayé de reconstruire ma formule en utilisant les requêtes hiérarchiques, mais au mieux j'obtiens une suite d'opérateurs...

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
WITH Formule AS (SELECT 1 id, '+' signe, 2 ssformid_gauche, 3 ssformid_droit, NULL const FROM  dual union ALL
SELECT 2 id, NULL signe, NULL ssformid_gauche, NULL ssformid_droit, 1 const FROM  dual union ALL
SELECT 3 id, '*' signe, 4 ssformid_gauche, 5 ssformid_droit, NULL const FROM dual union ALL
SELECT 4 id, '*' signe, 6 ssformid_gauche, 7 ssformid_droit, NULL const FROM dual union ALL
SELECT 5 id, '*' signe, 8 ssformid_gauche, 9 ssformid_droit, NULL const FROM dual union ALL
SELECT 6 id, NULL signe, NULL ssformid_gauche, NULL ssformid_droit, 2 const FROM dual union ALL
SELECT 7 id, NULL signe, NULL ssformid_gauche, NULL ssformid_droit, 3 const FROM dual union ALL
SELECT 8 id, NULL signe, NULL ssformid_gauche, NULL ssformid_droit, 4 const FROM dual union ALL
SELECT 9 id, NULL signe, NULL ssformid_gauche, NULL ssformid_droit, 5 const FROM dual 
)
SELECT Level, f.*,
       SYS_CONNECT_BY_PATH(nvl(signe, const), ' ')
FROM formule f
 Start WITH ID = 1
 connect BY (Prior ssformid_gauche = ID OR Prior ssformid_droit = ID)
J'ai représenté l 'arbre suivant :
 +
/ \
1  *
  / \
 *   *
/ \ / \
2 3 4 5
et je veux en sortie : 1+2*3*4*5

Merci
spdev666 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/01/2012, 19h22   #2
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 687
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 687
Points : 10 442
Points : 10 442
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
Pas évident en 10g.
Je ne pense pas qu'on puisse utiliser connect by ici, car on n'a aucune idée de la façon dont Oracle va faire la récursion, hors ici il faut d'abord connecter sur la gauche avant de connecter sur la droite.
Avec les opérateurs commutatifs ça ne pose pas de soucis, mais si vous voulez utiliser - et / ça ne marchera plus.

Probablement faisable en 11gR2 avec les r-CTE.

Mes résultats de bidouilles :
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
44
WITH Formule AS
(
SELECT 1 id, '+' signe, 2 ssformid_gauche, 3 ssformid_droit, NULL const FROM dual union ALL
SELECT 2   , NULL     , NULL             , NULL            , 1          FROM dual union ALL
SELECT 3   , '*'      , 4                , 5               , NULL       FROM dual union ALL
SELECT 4   , '*'      , 6                , 7               , NULL       FROM dual union ALL
SELECT 5   , '*'      , 8                , 9               , NULL       FROM dual union ALL
SELECT 6   , NULL     , NULL             , NULL            , 2          FROM dual union ALL
SELECT 7   , NULL     , NULL             , NULL            , 3          FROM dual union ALL
SELECT 8   , NULL     , NULL             , NULL            , 4          FROM dual union ALL
SELECT 9   , NULL     , NULL             , NULL            , 5          FROM dual
)
  ,  SR1 AS
(
    SELECT level
         , rownum AS rn
         , id
         , prior id
         , coalesce(signe, to_char(const)) AS ope
         , connect_by_isleaf AS cbi
      FROM formule f
START WITH ID = 1
CONNECT BY ID IN (prior ssformid_gauche, prior ssformid_droit)
)
  ,  SR2 AS
(
SELECT sr1.*
     , case 
         when cbi = 0
          AND lead(cbi, 1) over(ORDER BY rn ASC) = 1
         then lead(rn , 1) over(ORDER BY rn ASC) + id / 100
         when cbi = 0
          AND lead(cbi, 1) over(ORDER BY rn ASC) = 0
         then lead(rn , 3) over(ORDER BY rn ASC) + id / 100
         else rn
       end ord
  FROM sr1
)
SELECT REPLACE(REPLACE(XMLAgg(XMLElement("x", ope) ORDER BY ord ASC), '</x>', ''), '<x>', '') AS formule
  FROM sr2;
 
FORMULE                                                                         
---------
1+2*3*4*5
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 17/01/2012, 08h24   #3
Membre régulier
 
Inscription : septembre 2008
Messages : 85
Détails du profil
Informations forums :
Inscription : septembre 2008
Messages : 85
Points : 89
Points : 89
Merci pour la réponse.
spdev666 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 16h18.


 
 
 
 
Partenaires

Hébergement Web