Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
568 connectés 

  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  Problème de requete sql..nécessité d'une requete récursive??

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Problème de requete sql..nécessité d'une requete récursive??

n°1158599
rlnd22
Posté le 24-07-2005 à 23:52:15  profilanswer
 

Bonjour,  
je suis sous SQL ORACLE
voilà dans ma table T_HISTORIQUE j'ai l'historique des numéros qu'a pris un élément:  
table T_HISTORIQUE dont les colonnes sont:
numéro initial "numInit"
numéro final   "numFin"
date de changement de numéro "dateChang"
 
A la création de mon élément, j'insère 0 dans "numéro initial" puis le numéro de mon élément dans "numéro final". Ensuite à chaque modification de numéro j'insère le numéro initial et final dans la table.
Un numéro ne peut etre utilisé qu'une seule fois meme si les éléments sont différents.
 
Je souhaite écrire une requete qui me ramène pour un dernier numéro final d'un élément donné,  
l'ensemble des numéros qu'il a pris, ainsi que les dates de changements!
(il n'y a pas de clé primaire unique qui me permette de tout ramener d'un coup)
Je n'arrive pas à écrire une telle requete!!
 
j'ai tenté  
 
SELECT T1.numInit, T1.numFin
FROM T_HISTORIQUE T1, T_HISTORIQUE T2
WHERE  
T1.numFin = T2.numInit
 
mais je voudrais aussi mettre la condition que le dernier numéro pris par mon élément soit un paramètre!
 
Si je peux faire cela en une requete ce serait bien   :)

mood
Publicité
Posté le 24-07-2005 à 23:52:15  profilanswer
 

n°1158694
betsamee
Asterisk Zeperyl
Posté le 25-07-2005 à 09:30:55  profilanswer
 

Je ne l'ai pas lue en entier mais j'ai trouve sur
http://sqlpro.developpez.com/SQL_AZ_991.html
un truc tres ressemblant

Citation :


5.1.2 Récursion
 
 
Nous allons maintenant voir comment fonctionne la récursivité au sein de SQL...
Pour cela construisons notre jeu d'essais :
 
 
CREATE TABLE T_VOLS_VLS
(VLS_ID       INTEGER NOT NULL PRIMARY KEY,
 VLS_REF      CHAR(6) NOT NULL,
 VLS_DEPART   VARCHAR(16),
 VLS_ARRIVEE  VARCHAR(16)) INSERT INTO T_VOLS_VLS VALUES (1, 'AF714', 'PARIS', 'MARSEILLE')
INSERT INTO T_VOLS_VLS VALUES (2, 'AL908', 'PARIS', 'LYON')
INSERT INTO T_VOLS_VLS VALUES (3, 'AF321', 'PARIS', 'BORDEAUX')
INSERT INTO T_VOLS_VLS VALUES (4, 'AF978', 'BORDEAUX', 'MARSEILLE')
INSERT INTO T_VOLS_VLS VALUES (5, 'AL478', 'BORDEAUX', 'NICE')
INSERT INTO T_VOLS_VLS VALUES (6, 'AL974', 'NICE', 'LYON')
INSERT INTO T_VOLS_VLS VALUES (7, 'AL451', 'BORDEAUX', 'LILLE')
INSERT INTO T_VOLS_VLS VALUES (8, 'AF158', 'MARSEILLE', 'LYON')
INSERT INTO T_VOLS_VLS VALUES (9, 'AF159', 'MARSEILLE', 'BORDEAUX')
INSERT INTO T_VOLS_VLS VALUES (10, 'AF189', 'LYON', 'NICE')
INSERT INTO T_VOLS_VLS VALUES (11, 'AL458', 'NICE', 'PARIS')
INSERT INTO T_VOLS_VLS VALUES (12, 'AL117', 'MARSEILLE', 'PARIS')
INSERT INTO T_VOLS_VLS VALUES (13, 'AL444', 'BORDEAUX', 'LYON')
INSERT INTO T_VOLS_VLS VALUES (14, 'AL400',  'BORDEAUX', 'NANTES')
INSERT INTO T_VOLS_VLS VALUES (15, 'AF601',  'LYON', 'NANTES')
 
 
Le but est de trouver s'il est possible det se rendre, par exemple de PARIS à NANTES ou bien de NICE à BORDEAUX...
 
 
WITH RECURSIVE trajet (depart, arrivee)
AS (SELECT VLS_DEPART, VLS_ARRIVEE
    FROM   T_VOLS_VLS
    UNION  ALL
    SELECT debut.depart, suite.VLS_ARRIVEE
    FROM   trajet debut
           INNER JOIN T_VOLS_VLS suite
                 ON debut.arrive = suite.VLS_DEPART)
SELECT *
FROM   trajet
WHERE  depart = 'NICE'
   AND arrivee = 'BORDEAUX'
 
 
 
En fait le travail de circulation dans l'arbre se fait dans la clause WITH RECURSIVE. L'expression principale de requête n'est là que pour filtrer les résultats.
Lors du premier cycle, les données sont les suivantes :
 
 
depart           arrivee          
---------------- ----------------  
BORDEAUX         BORDEAUX
BORDEAUX         LILLE
BORDEAUX         LYON
BORDEAUX         LYON
BORDEAUX         LYON
BORDEAUX         MARSEILLE
BORDEAUX         NANTES
BORDEAUX         NANTES
BORDEAUX         NICE
BORDEAUX         NICE
BORDEAUX         PARIS
BORDEAUX         PARIS
LYON             LYON
LYON             NANTES
LYON             NICE
LYON             PARIS
MARSEILLE        BORDEAUX
MARSEILLE        BORDEAUX
MARSEILLE        LILLE
MARSEILLE        LYON
MARSEILLE        LYON
MARSEILLE        LYON
MARSEILLE        MARSEILLE
MARSEILLE        MARSEILLE
MARSEILLE        NANTES
MARSEILLE        NANTES
MARSEILLE        NICE
MARSEILLE        NICE
MARSEILLE        PARIS
NICE             BORDEAUX
NICE             LYON
NICE             LYON
NICE             MARSEILLE
NICE             NANTES
NICE             NICE
NICE             PARIS
PARIS            BORDEAUX
PARIS            BORDEAUX
PARIS            LILLE
PARIS            LYON
PARIS            LYON
PARIS            LYON
PARIS            MARSEILLE
PARIS            MARSEILLE
PARIS            NANTES
PARIS            NANTES
PARIS            NICE
PARIS            NICE
PARIS            PARIS
 
 
Nous avons en fait tous les trajets possibles directs ou avec une escale. A notez que si nous avions utilisé UNION au lieu de UNION ALL nous aurions eût moins de résultats, en fait 31 au lieu de 49, cela aurait signifié que nous nous fichons de savoir quelle est la ville étpae de l'escale !
Lors du second cycle les données sont :
 
 
depart           arrivee          
---------------- ----------------  
BORDEAUX         BORDEAUX
BORDEAUX         BORDEAUX
BORDEAUX         BORDEAUX
BORDEAUX         LILLE
BORDEAUX         LILLE
BORDEAUX         LYON
BORDEAUX         LYON
BORDEAUX         LYON
BORDEAUX         LYON
BORDEAUX         LYON
BORDEAUX         LYON
BORDEAUX         LYON
BORDEAUX         MARSEILLE
BORDEAUX         MARSEILLE
BORDEAUX         MARSEILLE
BORDEAUX         MARSEILLE
BORDEAUX         NANTES
BORDEAUX         NANTES
BORDEAUX         NANTES
BORDEAUX         NANTES
BORDEAUX         NANTES
BORDEAUX         NICE
BORDEAUX         NICE
BORDEAUX         NICE
BORDEAUX         NICE
BORDEAUX         NICE
BORDEAUX         PARIS
BORDEAUX         PARIS
BORDEAUX         PARIS
LYON             BORDEAUX
LYON             LYON
LYON             LYON
LYON             MARSEILLE
LYON             NANTES
LYON             NANTES
LYON             NICE
LYON             NICE
LYON             PARIS
MARSEILLE        BORDEAUX
MARSEILLE        BORDEAUX
MARSEILLE        BORDEAUX
MARSEILLE        BORDEAUX
MARSEILLE        LILLE
MARSEILLE        LILLE
MARSEILLE        LYON
MARSEILLE        LYON
MARSEILLE        LYON
MARSEILLE        LYON
MARSEILLE        LYON
MARSEILLE        LYON
MARSEILLE        LYON
MARSEILLE        LYON
MARSEILLE        MARSEILLE
MARSEILLE        MARSEILLE
MARSEILLE        MARSEILLE
MARSEILLE        NANTES
MARSEILLE        NANTES
MARSEILLE        NANTES
MARSEILLE        NANTES
MARSEILLE        NANTES
MARSEILLE        NICE
MARSEILLE        NICE
MARSEILLE        NICE
MARSEILLE        NICE
MARSEILLE        NICE
MARSEILLE        PARIS
MARSEILLE        PARIS
MARSEILLE        PARIS
MARSEILLE        PARIS
MARSEILLE        PARIS
NICE             BORDEAUX
NICE             BORDEAUX
NICE             LILLE
NICE             LYON
NICE             LYON
NICE             LYON
NICE             LYON
NICE             LYON
NICE             MARSEILLE
NICE             MARSEILLE
NICE             NANTES
NICE             NANTES
NICE             NANTES
NICE             NICE
NICE             NICE
NICE             NICE
NICE             PARIS
NICE             PARIS
NICE             PARIS
PARIS            BORDEAUX
PARIS            BORDEAUX
PARIS            BORDEAUX
PARIS            BORDEAUX
PARIS            LILLE
PARIS            LILLE
PARIS            LYON
PARIS            LYON
PARIS            LYON
PARIS            LYON
PARIS            LYON
PARIS            LYON
PARIS            LYON
PARIS            LYON
PARIS            MARSEILLE
PARIS            MARSEILLE
PARIS            MARSEILLE
PARIS            MARSEILLE
PARIS            NANTES
PARIS            NANTES
PARIS            NANTES
PARIS            NANTES
PARIS            NANTES
PARIS            NICE
PARIS            NICE
PARIS            NICE
PARIS            NICE
PARIS            NICE
PARIS            PARIS
PARIS            PARIS
PARIS            PARIS
PARIS            PARIS
 
 

n°1158699
megadub
Posté le 25-07-2005 à 09:37:36  profilanswer
 

Sous Oracle c'est l'opérateur CONNECT BY PRIOR qu'il faut utiliser ;)
 

Code :
  1. SELECT numInit, numFin
  2. FROM T_HISTORIQUE
  3. STAR WITH numInit = 0
  4. CONNECT BY PRIOR numFin = numInit


 
START WITH ne doit pas être obligatoire, ça te permet de commencer la hiérarchie où tu veux.
 
Un exemple bien connu de cette fonction est la requête de restitution du plan d'exécution qui permet de mettre en page :
 

Code :
  1. select LPAD(' ',2*(LEVEL-1))||operation  "OPERATION",
  2. options     "TYPE_ACCES",
  3. DECODE(TO_CHAR(id),'0','COST= '|| NVL(TO_CHAR(position),'Indefini'), object_name) "NOM_OBJET",
  4. id || '-' || NVL(parent_id,0) || '-' || NVL(position,0) "ORDRE",
  5. ' COUT=' || COST ||','||'Card=' || CARDINALITY "Cout Op"
  6. From plan_table
  7. start with id = 0
  8. and statement_id = 'X'
  9. connect by prior id = parent_id
  10. and statement_id = 'X';


n°1158740
betsamee
Asterisk Zeperyl
Posté le 25-07-2005 à 10:08:14  profilanswer
 

j'en profite;
existe t'il un equivalent de ces fonctions sous MYSQL (au vu de la doc je crois pas mais bon...)

n°1158743
megadub
Posté le 25-07-2005 à 10:08:55  profilanswer
 

ça ne me surprendrait que moyennement :D
 
Mais je dois admettre que je ne sais pas :/

n°1159058
Arjuna
Aircraft Ident.: F-MBSD
Posté le 25-07-2005 à 14:43:36  profilanswer
 

Nope, pas plus que sous SQL Server (grosse lacune d'ailleurs).
 
Sous SQL Server, on peut s'en tirer avec une PS, pour MySQL, à moins d'avoir la toute dernière version qui supporte aussi les PS, je pense que t'es obligé de passer par du code PHP ou autre.

n°1162403
matthieu_p​hpmv
Posté le 28-07-2005 à 00:08:41  profilanswer
 

En fait il doit y avoir 2 écoles :
- ceux qui veulent tout faire en SQL car ils préfèrent
- ceux qui, comme moi, trouvent que ces problèmes sont parfaits à résoudre avec un langage de programation fait pour, sans faire faire tout le travail au SGBD.
 
A mon avis les 2 avis sont bons, mais à voir niveau rapidité (ce qui doit dépendre de bcp de facteurs).

n°1604096
SQLpro
expert SGBD, SQL, modélisation
Posté le 26-08-2007 à 12:35:38  profilanswer
 

La création de requêtes récursive à la norme SQL:1999 (WITH RECURSIVE / UNION ALL) existe dans les SGBDR suivants :
IBM DB2 v8 et suivants
SQL Server 2005 (et 2008)
Elle n'existe pas dans les autres SGBDR comme MySQL, Oracle, PostGreSQL, Interbase, FireBird....
 
Oracle propose CONNECT BY / PRIOR, mais ne peut traiter que le parcours d'arbres par le parcours de graphes. C'est une lacule du moteur Oracle et c'est pourquoi le commité de normalisation de SQL n'a pas retenue la solution de Oracle.
 
Pour des détails sur les requêtes récursives, vous trouverez bientôt un article complet sur mon site : http://sqlpro.developpez.com (ou http://sql.developpez.com)
 
Quand à faire cela sur le client, c'est une simple problématique de perf. Sivous avez peu de données et une profondeur de scrutation récursive très faible, c'est faisable. Mais au volume de données ce sera toujours le SGBDR qui gagnera car il optimise et évite les aller et retour entre le serveur et le client.
 
A +
 

n°1604418
MagicBuzz
Posté le 27-08-2007 à 14:20:39  profilanswer
 

betsamee a écrit :

Je ne l'ai pas lue en entier mais j'ai trouve sur
http://sqlpro.developpez.com/SQL_AZ_991.html
un truc tres ressemblant


Ton site avait déjà été indiqué dès le départ ;)
 
Très bon article en tout cas :jap:
 
Vu que t'as l'air de t'y connaître bien plus que moi, je te propose de regarder ça :
http://forum.hardware.fr/hfr/Progr [...] 6416_1.htm
 
Et me dire ce que tu en penses, les erreurs, les trucs à ajouter, etc. ;)


Message édité par MagicBuzz le 27-08-2007 à 14:21:58

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  Problème de requete sql..nécessité d'une requete récursive??

 

Sujets relatifs
Probleme de script avec un formulaire[php] probleme de cache
Probleme de précision avec les tracés java2Dprobleme creation de miniatures
[Flash/ActionScript] Problème de loadNumMovie()Problème de tableaux :s
Problème de feuille d'envoi et d'image par java .Probleme compatibilité d'un site entre FireFox et IE
Probleme dácces a des id avec des [ ] et getElementByIdProblème de guillemet.
Plus de sujets relatifs à : Problème de requete sql..nécessité d'une requete récursive??


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR