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 :

Fonction analytique : Compter en fonction d'une rupture


Sujet :

SQL Oracle

  1. #1
    Membre habitué

    Inscrit en
    Février 2005
    Messages
    356
    Détails du profil
    Informations forums :
    Inscription : Février 2005
    Messages : 356
    Points : 175
    Points
    175
    Par défaut Fonction analytique : Compter en fonction d'une rupture
    Bonjour,

    Voilà je souhaite récupérer le nombre de magasin en fonction de la rupture CodeMagasin.

    Voici un exemple pour être plus clair :
    Cette requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT JourDeVente, CodeMagasin  
      FROM AGREGAT_TICKET_VENTE
     WHERE CodeClient = :CodeClient
     ORDER BY JourDeVente DESC
    me retourne


    Je souhaite que ma requête me retourne :
    22/12/2007 16 2
    27/01/2007 16 2
    24/01/2007 17 3
    16/12/2006 17 3
    12/12/2006 17 3
    14/07/2006 16 1
    13/07/2006 18 1

    J'ai essayé avec ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT JourDeVente, CodeMagasin, COUNT(*) OVER(PARTITION BY CodeMagasin) CNT  
      FROM AGREGAT_TICKET_VENTE
     WHERE CodeClient = :CodeClient
     GROUP BY JourDeVente, CodeMagasin
     ORDER BY JourDeVente DESC
    il me retourne :
    22/12/2007 16 3
    27/01/2007 16 3
    24/01/2007 17 3
    16/12/2006 17 3
    12/12/2006 17 3
    14/07/2006 16 3
    13/07/2006 18 1

    Il ne tient pas compte de la rupture CodeMagasin. Il effectue un count sur CodeMagasin en fonction de toutes les lignes retourné.

    Comment puis-je faire ?

  2. #2
    Membre habitué
    Inscrit en
    Mai 2010
    Messages
    107
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 107
    Points : 132
    Points
    132
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT JourDeVente, CodeMagasin, COUNT(CodeMagasin) OVER(PARTITION BY CodeMagasin) CNT

  3. #3
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Il faut rajouter une étape intermédiaire qui calcule vraiment la rupture, on le fait ainsi :
    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
    24
    25
    26
    27
    28
    29
    30
    31
    With AGREGAT_TICKET_VENTE as
    (
    select to_date('22/12/2007', 'dd/mm/yyyy') as JourDeVente, 16 as CodeMagasin from dual union all
    select to_date('27/01/2007', 'dd/mm/yyyy')               , 16                from dual union all
    select to_date('24/01/2007', 'dd/mm/yyyy')               , 17                from dual union all
    select to_date('16/12/2006', 'dd/mm/yyyy')               , 17                from dual union all
    select to_date('12/12/2006', 'dd/mm/yyyy')               , 17                from dual union all
    select to_date('14/07/2006', 'dd/mm/yyyy')               , 16                from dual union all
    select to_date('13/07/2006', 'dd/mm/yyyy')               , 18                from dual
    )
      ,  atv as
    (
    SELECT JourDeVente, CodeMagasin,
           row_number() over(                         order by JourDeVente desc) -
           row_number() over(partition by CodeMagasin order by JourDeVente desc) as grp 
      FROM AGREGAT_TICKET_VENTE
    )
      select JourDeVente, CodeMagasin,
             count(*) over(partition by CodeMagasin, grp) as CNT  
        from atv
    ORDER BY JourDeVente DESC;
     
    JourDeVente CodeMagasin        CNT
    ----------- ----------- ----------
     22/12/2007          16          2
     27/01/2007          16          2
     24/01/2007          17          3
     16/12/2006          17          3
     12/12/2006          17          3
     14/07/2006          16          1
     13/07/2006          18          1
    Notez également que les fonctions de fenêtrage ne s'appuient pas sur la clause GROUP BY de votre requête, celui de votre requête n'effectue au final qu'un simple (et probablement inutile) DISTINCT.

  4. #4
    Membre habitué

    Inscrit en
    Février 2005
    Messages
    356
    Détails du profil
    Informations forums :
    Inscription : Février 2005
    Messages : 356
    Points : 175
    Points
    175
    Par défaut
    Merci Waldar,

    Ta méthode fonctionne correctement même s'il est un peu difficile de comprendre !

  5. #5
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Attention j'ai apporté une correction sur le code (dans le dernier partition by).

    Pour comprendre, il faut décomposer tous les éléments !

  6. #6
    Membre habitué

    Inscrit en
    Février 2005
    Messages
    356
    Détails du profil
    Informations forums :
    Inscription : Février 2005
    Messages : 356
    Points : 175
    Points
    175
    Par défaut
    Oui avant d'écrire cette réponse, j'étais en train de décomposer le code et j'ai relevé une erreur si on enlevait la ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT to_date('12/12/2006', 'dd/mm/yyyy')               , 17                FROM dual union ALL
    J'ai lu ton nouveau message et donc avec ton correctif, ça solutionne le problème observé.

    Merci

  7. #7
    Rédacteur

    Homme Profil pro
    Développeur et DBA Oracle
    Inscrit en
    Octobre 2006
    Messages
    878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur et DBA Oracle

    Informations forums :
    Inscription : Octobre 2006
    Messages : 878
    Points : 1 197
    Points
    1 197
    Par défaut
    Bonjour,

    Une autre solution avec la 10g
    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
     
    WITH AGREGAT_TICKET_VENTE AS
    (
    SELECT to_date('22/12/2007', 'dd/mm/yyyy') AS JourDeVente, 16 AS CodeMagasin FROM dual union ALL
    SELECT to_date('27/01/2007', 'dd/mm/yyyy')               , 16                FROM dual union ALL
    SELECT to_date('24/01/2007', 'dd/mm/yyyy')               , 17                FROM dual union ALL
    SELECT to_date('16/12/2006', 'dd/mm/yyyy')               , 17                FROM dual union ALL
    SELECT to_date('12/12/2006', 'dd/mm/yyyy')               , 17                FROM dual union ALL
    SELECT to_date('14/07/2006', 'dd/mm/yyyy')               , 16                FROM dual union ALL
    SELECT to_date('13/07/2006', 'dd/mm/yyyy')               , 18                FROM dual
    ), 
    t as (
    SELECT JourDeVente,CodeMagasin,grp
      FROM agregat_ticket_vente
     model 
     dimension by ( row_number()over(partition by 1 order by JourDeVente desc) rn)
     measures(CodeMagasin,JourDeVente, 0 grp)ignore nav
     (grp[rn]=case  when nvl(CodeMagasin[cv()-1],CodeMagasin[cv()])=CodeMagasin[cv()] then 
                         grp[cv()-1]  
                    else grp[cv()-1]+1  end ))
    SELECT jourdevente, codemagasin, COUNT (grp) OVER (PARTITION BY grp)cpt
      FROM t
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
     
    JOURDEVENT CODEMAGASIN        CPT
    ---------- ----------- ----------
    2007-12-22          16          2
    2007-01-27          16          2
    2007-01-24          17          3
    2006-12-16          17          3
    2006-12-12          17          3
    2006-07-14          16          1
    2006-07-13          18          1
     
     
    7 rows selected.

  8. #8
    Nouveau Candidat au Club
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2013
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2013
    Messages : 1
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par pepito62 Voir le message
    Oui avant d'écrire cette réponse, j'étais en train de décomposer le code et j'ai relevé une erreur si on enlevait la ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT to_date('12/12/2006', 'dd/mm/yyyy')               , 17                FROM dual union ALL
    J'ai lu ton nouveau message et donc avec ton correctif, ça solutionne le problème observé.

    Merci

    Bonjour,

    Je comprends qu'un correctif a été apporté, notamment sur le problème observé (suppression du jeu de données de la ligne '12/12/2006') : aussi en reprenant le code de Waldar je m'aperçois que l'erreur subsiste.

    Pourriez-vous m'indiquer quelle correction a été apportée ?
    D'avance merci pour vos réponses.

  9. #9
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Quelle erreur constatez-vous ?
    Le code a été corrigé dans l'heure où j'avais posté mon message et portait sur la ligne #19 où j'avais initialement écrit count(*) over(partition by grp) au lieu de count(*) over(partition by CodeMagasin, grp).

    J'ai rejoué la requête en commentant la ligne du 12/12 et obtiens bien un résultat cohérent.

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

Discussions similaires

  1. compter en fonction d'une condition dans un formulaire
    Par Stéph utilisateur d'acces dans le forum IHM
    Réponses: 4
    Dernier message: 22/06/2011, 14h22
  2. Réponses: 6
    Dernier message: 29/07/2009, 15h31
  3. Réponses: 5
    Dernier message: 29/05/2009, 12h28
  4. Calcul d'une fonction analytique inverse
    Par matxl dans le forum Mathématiques
    Réponses: 3
    Dernier message: 31/05/2008, 14h15
  5. une fonction analytique ?
    Par boutte dans le forum SQL
    Réponses: 10
    Dernier message: 20/06/2007, 09h45

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