IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PL/SQL Oracle Discussion :

Manque une jointure dans cette requête


Sujet :

PL/SQL Oracle

  1. #1
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    juillet 2016
    Messages
    176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : juillet 2016
    Messages : 176
    Points : 88
    Points
    88
    Par défaut Manque une jointure dans cette requête
    Bonjour,
    J'ai une requête qui renvoie plusieurs fois la même ligne. Il manque une jointure visiblement mais je n'arrive pas à trouver où. Pourriez-vous m'aider ? Je suis sous Oracle 12.1. Voici la requête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    with 
    r as (
    select trunc(t.date_travaux, 'yyyy') date_travaux, sum(t.montant_facture) montant_facture from mv_entretien t
    GROUP by trunc(t.date_travaux, 'yyyy')), 
    y as (select date1,cout_carburant from mv_cout_carburant where vehicule = :P13_VEHICULE)
    select trunc(a.date_kilometrage, 'yyyy') "Année", a.kilometrage "Kilométrage", (r.montant_facture+y.cout_carburant)/a.kilometrage "Prix de revient km"
    from mv_kilometrage a, r, y, mv_entretien z
    where trunc(r.date_travaux, 'yyyy') = trunc(a.date_kilometrage, 'yyyy')
    and trunc(y.date1, 'yyyy') = trunc(a.date_kilometrage, 'yyyy')
    and a.vehicule=:P13_VEHICULE
    AND z.type_travaux <> 4
    order by a.date_kilometrage;
    Le résultat est :

    01/01/2014 00:00:00 14806 0,0728751857355126300148588410104011887073
    01/01/2014 00:00:00 14806 0,0728751857355126300148588410104011887073
    01/01/2014 00:00:00 14806 0,0728751857355126300148588410104011887073
    01/01/2015 00:00:00 26222 0,0412783159179315078941346960567462436122
    01/01/2015 00:00:00 26222 0,0412783159179315078941346960567462436122
    01/01/2015 00:00:00 26222 0,0412783159179315078941346960567462436122
    01/01/2016 00:00:00 38950 0,0223211810012836970474967907573812580231
    01/01/2016 00:00:00 38950 0,0223211810012836970474967907573812580231
    01/01/2016 00:00:00 38950 0,0223211810012836970474967907573812580231
    01/01/2017 00:00:00 48827 0,1086548426075736784975525836115264095685
    01/01/2017 00:00:00 48827 0,1086548426075736784975525836115264095685
    01/01/2017 00:00:00 48827 0,1086548426075736784975525836115264095685

    Merci pour votre aide.

  2. #2
    Modérateur

    Homme Profil pro
    Consultant Teradata
    Inscrit en
    septembre 2008
    Messages
    8 118
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant Teradata

    Informations forums :
    Inscription : septembre 2008
    Messages : 8 118
    Points : 16 347
    Points
    16 347
    Par défaut
    Comme ça je pense que c'est mv_entretien (alias z) dans la requête principale qui est en trop.
    Regardez si vous pouvez remonter le filtre dans la CTE r.
    Et utilisez la syntaxe JOIN, comme ça vous le voyez tout de suite :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    with cte_r as
    (
      select trunc(date_travaux, 'yyyy') as date_travaux
           , sum(montant_facture)        as montant_facture
        from mv_entretien
       where type_travaux <> 4
    group by trunc(date_travaux, 'yyyy')
    )
      select trunc(a.date_kilometrage, 'yyyy') as "Année"
           , a.kilometrage                     as "Kilométrage"
           , case a.kilometrage
               when 0
               then 0
               else (r.montant_facture + y.cout_carburant) / a.kilometrage
             end as "Prix de revient km"
        from mv_kilometrage    a
        join cte_r             r  on r.date_travaux         = trunc(a.date_kilometrage, 'yyyy')
        join mv_cout_carburant y  on trunc(y.date1, 'yyyy') = trunc(a.date_kilometrage, 'yyyy')
       where a.vehicule = :P13_VEHICULE
         and y.vehicule = :P13_VEHICULE
    order by a.date_kilometrage;
    Après les jointures sur l'année ça me paraît pas terrible non plus. Montrez-nous les données de vos trois tables (sur un petit jeu d'essai cohérent).

  3. #3
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    juillet 2016
    Messages
    176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : juillet 2016
    Messages : 176
    Points : 88
    Points
    88
    Par défaut
    Merci pour votre réponse. J'obtiens ce résultat :

    01/01/2014 00:00:00 14806 0,0728751857355126300148588410104011887073
    01/01/2015 00:00:00 26222 0,0412783159179315078941346960567462436122
    01/01/2016 00:00:00 38950 0,0223211810012836970474967907573812580231

    C'est bien sauf que n'apparaît pas l'année 2017 où justement il y a eu un type_travaux = 4 (la dernière ligne de la table MV_ENTRETIEN). C'est normal puisque je l'exclus (TYPE_TRAVAUX <> 4) dès le départ. mais je voudrais calculer les frais km en tenant compte du fait qu'il y a eu des type_travaux = à 4.

    La table MV_ENTRETIEN:

    1 révision 1er année 28/10/2014 00:00:00 12533 179 morsang auto 1
    1 révision 2 éme année réparation pare brise 27/10/2015 00:00:00 23760 375 morsang auto 1
    1 réparation roue avg 01/10/2016 00:00:00 24050 16,21 ayme et fils 5
    1 reparation choc lateral D 27/12/2017 00:00:00 44686 4640,84 lmauto 4

    La table MV_KILOMETRAGE :

    1 14806 31/12/2014 00:00:00 2
    1 26222 31/12/2015 00:00:00 4
    1 38950 31/12/2016 00:00:00 5
    1 48827 31/12/2017 00:00:00 6

    La table COUT_CARBURANT :

    1 31/12/2014 00:00:00 899,99
    1 31/12/2015 00:00:00 707,4
    1 31/12/2016 00:00:00 853,2
    1 31/12/2017 00:00:00 664,45

  4. #4
    Nouveau membre du Club
    Homme Profil pro
    Consultant MOE-MOA Finance
    Inscrit en
    novembre 2019
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Consultant MOE-MOA Finance
    Secteur : Finance

    Informations forums :
    Inscription : novembre 2019
    Messages : 17
    Points : 36
    Points
    36
    Par défaut
    Bonsoir,
    j'ai repris votre requête initiale:
    Vous avez le résultat en triple parce que vous faites un produit cartésien (table Z sans aucune jointure) avec la table Z (Type_travaux) sans la ligne 4 (donc il reste 3 lignes c'est pour ça que le résultat est en triple)

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    with 
    r as (
           select trunc(t.date_travaux, 'yyyy') date_travaux, 
    	          --ici si type travaux = 4 on prend 0 à la place du montant facture sinon on prend le montant facture
    	          sum(decode( t.type_travaux, 4, 0, t.montant_facture)) montant_facture 
    	   from   mv_entretien t
           GROUP by trunc(t.date_travaux, 'yyyy')), 
    y as ( select date1,cout_carburant from mv_cout_carburant where vehicule = :P13_VEHICULE)
    select trunc(a.date_kilometrage, 'yyyy') "Année", a.kilometrage "Kilométrage", (r.montant_facture+y.cout_carburant)/a.kilometrage "Prix de revient km"
    from mv_kilometrage a, r, y --, mv_entretien z
    where trunc(r.date_travaux, 'yyyy') = trunc(a.date_kilometrage, 'yyyy')
    and trunc(y.date1, 'yyyy') = trunc(a.date_kilometrage, 'yyyy')
    and a.vehicule=:P13_VEHICULE
    --AND z.type_travaux <> 4
    order by a.date_kilometrage;

  5. #5
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    juillet 2016
    Messages
    176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : juillet 2016
    Messages : 176
    Points : 88
    Points
    88
    Par défaut
    Merci Mahdois.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 15/12/2018, 15h42
  2. [AC-2010] Comment rajouter une jointure dans requête existante
    Par py86acces dans le forum Requêtes et SQL.
    Réponses: 13
    Dernier message: 12/09/2015, 09h48
  3. Réponses: 2
    Dernier message: 12/01/2008, 14h57
  4. Remplacer une jointure dans une requête DELETE
    Par lorant dans le forum Requêtes
    Réponses: 5
    Dernier message: 30/11/2006, 19h46
  5. Optimiser les jointures dans des requêtes
    Par klereth dans le forum PostgreSQL
    Réponses: 12
    Dernier message: 23/04/2005, 17h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo