Probleme de comptage (SQL Oracle)

Probleme de comptage (SQL Oracle) - SQL/NoSQL - Programmation

Marsh Posté le 02-01-2014 à 10:41:48    

Bonjour à tous,
 
Je reçois un fichier plat d’un SI amont qui liste les trajets effectués. Pour des besoins d’analyse, nous voudrions compter le nombre de trajets « continus »  
= compter « 1 » pour la ligne 1 et 2 car le lieu d’arrivée de la ligne 1 est identique au lieu de départ de la ligne 2  (Paris).  
 
En revanche, le lieu d’arrivé de la ligne 2 et le lieu de départ de la ligne 3 sont différents donc il faut compter 1 pour la ligne 3
 
La règle de gestion serait donc de « compter 1 » quand la valeur du champ ARRIVEE de la ligne n-1 est identique à la valeur du champ DEPART de la ligne n
 
FICHIER SOURCE  
LIGNE    DEPART        ARRIVEE         CALCUL SOUHAITE
1          ROUEN         PARIS                         1
2          PARIS           LYON  
3          MARSEILLE    PARIS                        1
4          NANTES        BORDEAUX                  1
 
 
Avez-vous des pistes pour ce comptage particulier?
 
Cordialement

Reply

Marsh Posté le 02-01-2014 à 10:41:48   

Reply

Marsh Posté le 02-01-2014 à 11:12:25    

Bonjour !
 
Quel est le lien entre votre problème et Oracle ? Vous insérez les données dans une base ? A quel moment ? ...
 
Car dans le texte, vous ne parlez que de fichier plat et de lignes.
 
Bonne continuation !

Reply

Marsh Posté le 02-01-2014 à 13:39:19    

bonjour,
je ne sais pas si en oracle, tu as la fonction rrn (ma table)...
si oui :
select a.*,                                                                              
case when b.a1 = a.d1 then 0 else 1 end
from "ton_fichier_plat" as a  left outer join "ton_fichier_plat"  as b            
on rrn(a) =rrn(b)- 1          
 
Guillaume
 
                 

Reply

Marsh Posté le 02-01-2014 à 15:57:08    

Salut
 
gpl73, "rrn" c'est pas tres parlant, si tu ne precises pas de quel systeme ca vient ni ce que ca fait, c'est dur de savoir s'il y a un equivalent Oracle...
 
Vu la requete que tu proposes, ca a l'air d'etre simplement le numero de ligne.
 
Effectivement on peut utiliser ca, mais faut raffiner un peu.  
tsf63, tes trajets peuvent-ils recouvrir plus de 2 lignes de ta table (ex: montpellier->lyon, lyon->paris, paris->rennes, rennes-> brest)?
Les trajets "complets" sont-ils valables seulement si les lignes se suivent?
Ex:
1 montpellier->lyon
2 paris->rennes
3 lyon->paris
C'est bien 3 trajets differents?


---------------
C'était vraiment très intéressant.
Reply

Marsh Posté le 02-01-2014 à 16:46:33    

Bon allez vite fait, en supposant que les reponses sont "oui", "oui" et que tu utilises une version d'Oracle recente.

 

Ca va partir de la:

SELECT t.ligne, SYS_CONNECT_BY_PATH(t.ligne,'/') AS path
FROM table t
CONNECT BY PRIOR t.ligne = t.ligne-1 AND PRIOR t.arrivee = t.depart;

Cette requete va te trouver tous les trajets - mais en incluant tous les sous-trajets, donc il va falloir s'en debarasser et transformer tout ca pour compter tranquille. J'ai la flemme de verifier des trucs dans la doc donc ca va etre un peu "alaouanegaine" m'enfin ca va marcher.

 

D'abord, tu calcules le nombre d'etapes de chaque trajet:

SELECT ligne, path, LENGTH(path)-LENGTH(REPLACE(path,'/','')) AS length FROM (
SELECT t.ligne, SYS_CONNECT_BY_PATH(t.ligne,'/') AS path
FROM table t
CONNECT BY PRIOR t.ligne = t.ligne-1 AND PRIOR t.arrivee = t.depart);

Ensuite tu filtres trajet avec le plus d'etapes par ligne:

SELECT ligne, MAX(length) FROM (
SELECT ligne, path, LENGTH(path)-LENGTH(REPLACE(path,'/','')) AS length FROM (
SELECT t.ligne, SYS_CONNECT_BY_PATH(t.ligne,'/') AS path
FROM table t
CONNECT BY PRIOR t.ligne = t.ligne-1 AND PRIOR t.arrivee = t.depart)) GROUP BY ligne;

Et la t'as quasi fini: pour ton comptage, toutes les lignes de longueur superieure a 1 comptent pour du beurre:

SELECT ligne, DECODE(length,1,1,0) AS compte_trajet FROM (
SELECT ligne, MAX(length) FROM (
SELECT ligne, path, LENGTH(path)-LENGTH(REPLACE(path,'/','')) AS length FROM (
SELECT t.ligne, SYS_CONNECT_BY_PATH(t.ligne,'/') AS path
FROM table t
CONNECT BY PRIOR t.ligne = t.ligne-1 AND PRIOR t.arrivee = t.depart)) GROUP BY ligne);

Et voila! T'as plus qu'a additioner compte_trajet.


Message édité par lasnoufle le 02-01-2014 à 16:47:37

---------------
C'était vraiment très intéressant.
Reply

Marsh Posté le 06-01-2014 à 11:34:51    

Bonjour à tous,
 
@gpl73 : Merci pour votre retour
@lasnoufle : Effectivement, les trajets peuvent recouvrir plus de 2 lignes sur la table. De plus, ils ne sont valables uniquement si les lignes se suivent. Enfin, Oracle 11g
Merci pour votre idée de solution, je vais l'adapter à ma db
 
Cordialement

Reply

Marsh Posté le 07-01-2014 à 13:59:25    

rrn, c'est le relative record number (notion qui existe sur AS400)
Je veux bien raffiner... mais sur des fichiers plats avec juste deux champs, sans index et où identifiant...  
autre que le numéro de ligne, et deux descriptions :)
comment veux tu raffiner ? :)
j'ai fait avec les moyens du bords, tel que tu nous l'as décrit...
 
NB. : le connect by prior t.ligne = t.ligne -1 de "lasnoufle" est kifkif  à mon rrn(a) = rrn(b)-1 ...

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed