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

SQL Oracle Discussion :

Calcul différence avec enregistrement précédent


Sujet :

SQL Oracle

  1. #1
    Membre à l'essai
    Homme Profil pro
    Particulier
    Inscrit en
    Février 2018
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Particulier
    Secteur : Transports

    Informations forums :
    Inscription : Février 2018
    Messages : 16
    Points : 11
    Points
    11
    Par défaut Calcul différence avec enregistrement précédent
    Bonjour,

    J'ai une table "Entretiens"

    vehicule date_entretien kilometrage
    v1 2022-01-01 3000
    v1 2022-01-15 4000
    v1 2022-07-25 11000
    v2 2022-03-05 350
    v2 2022-04-06 1500
    v2 2022-08-06 3200

    Dans le résultat de ma requête je souhaite avoir la différence de kilomètres avec l'entretien précédent de ce même véhicule. En gros :

    vehicule date_entretien delta_kilometrage
    v1 2022-01-01
    v1 2022-01-15 1000
    v1 2022-07-25 7000
    v2 2022-03-05
    v2 2022-04-06 1150
    v2 2022-08-06 1700

    J'ai rédigé ma requête de la sorte :
    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
    22
    23
     
    SELECT
         ENT.VEHICULE,
         ENT.DATE_ENTRETIEN,
        (ENT.KMS - ENT3.KMS) AS DELTA_KILOMETRAGE
    FROM
        ENTRETIENS AS ENT
       LEFT JOIN
       (
           SELECT
              ENT2.VEHICLE,
              ENT2.DATE_ENTRETIEN,
              ENT2.KMS
              RANK() OVER (PARTITION BY ENT2.VEHICULE ORDER BY ENT2.DATE_ENTRETIEN DESC) AS RNK
           FROM
              ENTRETIENS AS ENT2
       ) ENT3 ON
           ENT.VEHICULE = ENT3.VEHICULE
           AND RNK = 1
           AND ENT3.DATE_ENTRETIEN < ENT.DATE_ENTRETIEN
    ORDER BY
        ENT.VEHICULE,
        ENT.DATE_ENTRETIEN
    Si je mets "RNK" à 1 je n'ai aucun calcul de delta :
    vehicule date_entretien delta_kilometrage
    v1 2022-01-01
    v1 2022-01-15
    v1 2022-07-25
    v2 2022-03-05
    v2 2022-04-06
    v2 2022-08-06

    Si je mets "RNK" à 2 j'ai bien le résultat pour le dernier résultat mais rien pour les entretiens précédents :
    vehicule date_entretien delta_kilometrage
    v1 2022-01-01
    v1 2022-01-15
    v1 2022-07-25 7000
    v2 2022-03-05
    v2 2022-04-06
    v2 2022-08-06 1700

    Je dois passer à côté de quelque chose, je suis preneur si quelqu'un voit ma boulette

  2. #2
    Membre chevronné
    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Décembre 2019
    Messages
    1 138
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Décembre 2019
    Messages : 1 138
    Points : 1 918
    Points
    1 918
    Par défaut
    Bonjour,

    Tu peux utiliser la fonction LAG pour ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT
    ENT.VEHICULE,
    ENT.DATE_ENTRETIEN,
    ENT.KMS - LAG(ENT.KMS) OVER (PARTITION BY ENT.VEHICULE ORDER BY ENT.DATE_ENTRETIEN) AS AS DELTA_KILOMETRAGE
    FROM
    ENTRETIENS AS ENT

  3. #3
    Membre à l'essai
    Homme Profil pro
    Particulier
    Inscrit en
    Février 2018
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Particulier
    Secteur : Transports

    Informations forums :
    Inscription : Février 2018
    Messages : 16
    Points : 11
    Points
    11
    Par défaut
    Vanagreg, merci pour ce début de réponse.
    La fonction LAG fonctionne parfaitement en l'intégrant à ma requête.

    Cette requête doit servir à générer des stats sur le delta entre deux entretiens pour différents intervalles de temps : années, mois, semaine, etc...

    Du coup, si j'étoffe mes données de départ :

    vehicule date_entretien kilometrage
    v1 2021-06-01 50
    v1 2022-01-01 3000
    v1 2022-01-15 4000
    v1 2022-07-25 11000
    v2 2022-03-05 350
    v2 2022-04-06 1500
    v2 2022-08-21 20874
    v3 2020-03-05 80
    v3 2021-04-06 10500
    v3 2022-07-06 22000

    Imaginons que je souhaite avoir un indicateur sur le mois de Juillet 2022 je ferais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    SELECT
        ENT.VEHICULE,
        ENT.DATE_ENTRETIEN,
        ENT.KMS - LAG(ENT.KMS) OVER (PARTITION BY ENT.VEHICULE ORDER BY ENT.DATE_ENTRETIEN) AS AS DELTA_KILOMETRAGE
    FROM
        ENTRETIENS AS ENT
    WHERE
       TO_CHAR(ENT.DATE_ENTRETIEN, 'MMYYYY') = '072022'
    Ce qui me fait des données erronées :
    vehicule date_entretien delta_kilometrage
    v1 2022-07-25
    v3 2022-07-06

    De ce que je vois des fonctions analytique, il reste dans la plage des critères de recherche.

  4. #4
    Membre chevronné
    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Décembre 2019
    Messages
    1 138
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Décembre 2019
    Messages : 1 138
    Points : 1 918
    Points
    1 918
    Par défaut
    C'est parce que les fonctions analytiques sont appliquées en dernier dans une requête, juste avant la clause ORDER BY finale. Donc ta clause WHERE est appliquée avant la fonction analytique, c'est pour cela que tu n'obtiens rien. Il faut d'abord encapsuler la requête, et ensuite appliquer la clause WHERE

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    SELECT *
    FROM(
    SELECT
        ENT.VEHICULE,
        ENT.DATE_ENTRETIEN,
        ENT.KMS - LAG(ENT.KMS) OVER (PARTITION BY ENT.VEHICULE ORDER BY ENT.DATE_ENTRETIEN) AS AS DELTA_KILOMETRAGE
    FROM
        ENTRETIENS AS ENT
    )
    WHERE
    ENT.DATE_ENTRETIEN BETWEEN TO_DATE('01072022', 'ddmmyyyy') AND TO_DATE('31072022', 'ddmmyyyy');

  5. #5
    Membre à l'essai
    Homme Profil pro
    Particulier
    Inscrit en
    Février 2018
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Particulier
    Secteur : Transports

    Informations forums :
    Inscription : Février 2018
    Messages : 16
    Points : 11
    Points
    11
    Par défaut
    Merci pour ce complément d'information.

    Ça fonctionne nickel

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

Discussions similaires

  1. Calculs utilisant les enregistrements précédents
    Par Kmilla dans le forum Requêtes et SQL.
    Réponses: 8
    Dernier message: 12/05/2017, 15h18
  2. [Débutant] calcul différence avec altitude différente ?
    Par MAJDO1989 dans le forum MATLAB
    Réponses: 1
    Dernier message: 06/05/2017, 12h58
  3. Afficher un champs calculé depuis les enregistrements précédents
    Par Interruption13h dans le forum Requêtes
    Réponses: 5
    Dernier message: 14/03/2011, 18h30
  4. valeur de champ actuel en relation avec l'enregistrement précédent
    Par NABIL74 dans le forum Bases de données
    Réponses: 10
    Dernier message: 10/12/2008, 18h57
  5. Petit Calcul à l'aide des enregistrements précédents
    Par laurentcr dans le forum Access
    Réponses: 5
    Dernier message: 11/09/2006, 13h41

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