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 :

Doublonnage sur agrégation


Sujet :

SQL Oracle

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 6
    Par défaut Doublonnage sur agrégation
    Bonjour,
    Voici donc le problème (sous Oracle 9.?) : l'utilisation d'une vue particulière, toujours la même, dans une jointure dans une requête entraîne des doublonnages de ligne mais uniquement lorsque j'utilise "directement" des fonctions d'agrégation. Sur un select simple ou en utilisant une sous requête dans la clause from, les résultats sont cohérents et jusqu'à preuve du contraire, il n'y a qu'une vue problématique dans la base.
    Les 3 exemples ci-dessous sont une illustration "simplifiée" du problème (pour la situation réelle, imaginez les mêmes requêtes avec 10 ou 20 variables et 2 ou 3 tables en plus et 10 millions de lignes en sortie mais la problématique est la même : dès que la vue en question est intégrée dans la requête, les résultats "explosent") :

    Exemple 1 : SELECT simple, résultat normal et conforme à l'attente :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT A, B FROM V1 NATURAL JOIN V2;
    4 lignes :
    A	B
    Val1	3
    Val2	1
    Val2	2
    Val2	1
    Exemple 2 : SELECT avec agrégation, résultats anormaux avec doublonnage des lignes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT A, SUM(B) AS SB, COUNT(*) AS Nb_lignes FROM V1 NATURAL JOIN V2 GROUP BY A;
    2 lignes :
    A	SB	Nb_lignes
    Val1	6	2
    Val2	8	6
    Exemple 3 : SELECT avec agrégation mais utilisation d'une sous requête dans la clause FROM, résultats normaux et conformes à l'attente :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT A, SUM(B) AS SB, COUNT(*) AS Nb_lignes FROM (SELECT * FROM V1 NATURAL JOIN V2) GROUP BY A;
    2 lignes :
    A	SB	Nb_lignes
    Val1	3	1
    Val2	4	3
    Je comprends bien, d'un point de vue technique, que l'exemple 3 fonctionne puisque la sélection se fait sur l'ensemble valide de l'exemple 1 reconstitué par la sous requête mais, sauf erreur de ma part, d'un point de vue logique, FROM (SELECT * FROM V1 NATURAL JOIN V2) et FROM V1 NATURAL JOIN V2 sont strictement équivalents, d'où la question : quelqu'un peut-il m'expliquer de ce qui peut provoquer le dérapage de l'exemple 2 ?!
    Merci d'avance
    (et avec toutes mes excuses si le problème n'est pas clair, a déjà été traité sans que je le retrouve ou si je ne suis pas dans la bonne rubrique pour le faire : je ne savais pas trop où aller dans la mesure où j'y suis confronté en tant qu'utilisateur mais qu'il relève a priori de l'administration)

  2. #2
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    J'ai essayé de construire un jeux d'essai (Oracle 10) très simple mais tout se passe bien:
    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
     
     
    create table t1 (
    a varchar2(10))
    /
    create table t2 (
    a varchar2(10),
    b number(1))
    /
    create view v1 as select * from t1
    /
    create view v2 as select * from t2
    /
    insert into v1 values ('Val1')
    /
    insert into v1 values ('Val2')
    /
    insert into v2 values ('Val1', 3)
    /
    insert into v2 values ('Val2', 1)
    /
    insert into v2 values ('Val2',2)
    /
    insert into v2 values ('Val2',1)
    /
    select a, b from v1 natural join v2
    /
    SELECT A, SUM(B) AS SB, COUNT(*) AS Nb_lignes FROM V1 NATURAL JOIN V2 GROUP BY A
    /
    SELECT A, SUM(B) AS SB, COUNT(*) AS Nb_lignes FROM (SELECT * FROM V1 NATURAL JOIN V2) GROUP BY A
    /
    Essayiez de matérialiser vos vues dans des table temporaire et vérifiez qu'elles ne contiens pas de doublons et que le résultat de la requête est correcte. Ou peut être vous pouvez nous fournir un jeux d'essai.

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 6
    Par défaut
    Merci de m'avoir consacré du temps et mes excuses car mon post était un cas typique de question mal posée avec des exemples erronés suite à un problème mal compris (à décharge, le soucis avait à l'origine été rencontré par une collègue).
    A défaut d'être "résolu", le problème est maintenant compris et voilà l'explication (suivie malgré tout d'une question), au cas où elle pourrait intéresser quelqu'un.
    En fait, les requêtes retournent des résultats incohérents lorsqu'elles sont de la forme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT {liste de variables quelconques} FROM V1 NATURAL JOIN V2 NATURAL JOIN V3;
    La liste de variables peut inclure ou nom des fonctions d'agrégation (avec bien sur un GROUP BY adapté en plus), ça n'a pas d'importance.
    Par contre, les résultats sont cohérents si la requête est de la forme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM V1 NATURAL JOIN V2 NATURAL JOIN V3;
    ou de la forme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT {liste de variables quelconques} FROM V1 NATURAL JOIN (V2 NATURAL JOIN V3);
    ou (parfois) de la forme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT {liste de variables quelconques}  FROM V2 NATURAL JOIN V3 NATURAL JOIN V1;
    Mais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT {liste de variables quelconques} FROM (V1 NATURAL JOIN V2) NATURAL JOIN V3;
    retourne aussi des résultats incohérents...
    Pour info, il y a de 0 à n lignes dans V3 pour chaque ligne de V2 et de 1 à n lignes dans V2 pour chaque ligne de V3.
    Le problème est que les tables V2 et V3 ont 8 variables communes alors que la table V1 n'a que 7 variables communes avec les tables V2 et V3 et que, par défaut, Oracle n'utilise que les 7 variables communes aux 3 tables pour l'ensemble des jointures.
    La jointure ne se passe correctement avec le NATURAL JOIN que si la jointure entre V2 et V3 est exécutée "de force" avant celle avec V1 ou si la 8e variable de jointure (commune à V2 et V3) est mentionnée dans le SELECT (d'où le fonctionnement cohérent du SELECT *), auquel cas Oracle semble se rappeler qu'il est censé s'en servir...

    Je sais que ce n'est pas un fonctionnement normal, Oracle étant censé, lors d'une jointure à plus de 2 tables, associer une paire de tables puis associer le résultat à une autre table et ainsi de suite (http://download-west.oracle.com/docs...s7.htm#2054014), sans parler des variables sélectionnées qui ont un impact sur la jointure... mais j'aimerais savoir si c'est un bug connu et généralisé d'Oracle (auquel cas je m'excuse encore une fois de vous faire perdre votre temps) ou s'il peut être lié à une caractéristique particulière de notre base et, éventuellement, corrigé ?
    Merci d'avance

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

Discussions similaires

  1. Test sur agrégat count
    Par halimux dans le forum Requêtes
    Réponses: 1
    Dernier message: 05/01/2012, 15h56
  2. log sur agrégation
    Par dingo200 dans le forum Développement de jobs
    Réponses: 4
    Dernier message: 17/06/2009, 14h36
  3. [DC] Relation/Agrégation/Composition sur Client->Adresse
    Par amazircool dans le forum Diagrammes de Classes
    Réponses: 15
    Dernier message: 15/01/2008, 12h27
  4. [SQL] agrégat sur deux granularitée différentes
    Par HurtMarley dans le forum Langage SQL
    Réponses: 2
    Dernier message: 15/06/2006, 11h39
  5. [TUNING] : Access full sur calculs d'agrégats
    Par PpPool dans le forum Oracle
    Réponses: 33
    Dernier message: 20/10/2005, 09h22

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