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 :

Requête avec multiples UNION. Puis-je faire autrement ? [11g]


Sujet :

SQL Oracle

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2005
    Messages : 49
    Par défaut Requête avec multiples UNION. Puis-je faire autrement ?
    Bonjour,

    J'ai effectué une requête avec multiple UNION. Bien qu'elle me retourne les résultats escomptés, je ne suis pas satisfait par sa complexité et je voudrais savoir s'il existe un autre moyen, sous Oracle 11G, d'éviter l'utilisation multiple d'Union pour obtenir mes différents calculs sur une seule ligne (celle d'un groupe).

    Voici ce que je veux obtenir.

    Nom : Sans titre.png
Affichages : 203
Taille : 4,5 Ko

    Pour chaque groupe d'un cours, je veux avoir la moyenne des étudiants présents, la moyenne de tous les étudiants.
    Enfin, je veux la moyenne de tous les étudiants présents de tous les groupes et la moyenne de tous les étudiants de tous les groupes.

    Il est vrai que je pourrais faire plusieurs requêtes, mais je souhaiterais réaliser ces calculs en une seule fois et éviter plusieurs appels BD dans mon programme.
    Et c'est surtout l'idée de savoir s'il existe un moyen de faire sans UNION qui m'intéresse.

    J'ai donc une requête qui ressemble à ça (J'ai simplifié le tout au max pour ne garder que le concept de ma requête) :

    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
     
    Select groupe, sum(noteEtu) / nbEtuObtenuAilleurs as moyenne_present, 0 as moyenne_tous, 0 as moyenne_total_present, 0 as moyenne_total_tous 
    from TableCours
    where etudiantPresent = '0'
    and cours = 'XXX'
    group by groupe
    UNION
    Select groupe, 0 moyenne_present, sum(noteEtu) / nbEtuObtenuAilleurs  as moyenne_tous, 0 as moyenne_total_present, 0 as moyenne_total_tous 
    from TableCours
    where cours = 'XXX'
    group by groupe
    UNION
    Select null, 0 as moyenne_present, 0 as moyenne_tous, sum(noteEtu) / nbEtuObtenuAilleurs  as moyenne_total_present, 0 as moyenne_total_tous 
    from TableCours
    where cours = 'XXX'
    UNION
    Select null, 0 as moyenne_present, 0 as moyenne_tous, 0 as moyenne_total_present, sum(noteEtu) / nbEtuObtenuAilleurs  as moyenne_total_tous 
    from TableCours
    where cours = 'XXX'

  2. #2
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Par défaut
    Bonjour,

    un descriptif des tables avec un jeu de données serait idéal pour mieux comprendre et tester rapidement des solutions à vous proposer.

    Mais ceci devrait être un bon début, à adapter :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT 
    		groupe
    	,	SUM(CASE WHEN etudiantPresent = '0' THEN NULL ELSE noteEtu END) / nbEtuObtenuAilleurs as moyenne_present
    	,	SUM(noteEtu) / nbEtuObtenuAilleurs as moyenne_tous
    FROM		TableCours
    WHERE		cours = 'XXX'
    GROUP BY	groupe 
    		WITH ROLLUP

  3. #3
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    La syntaxe sous Oracle est la suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
      select groupe
           , sum(case when etudiantPresent = '0' then null else noteEtu end) / nbEtuObtenuAilleurs as moyenne_present
           , sum(noteEtu) / nbEtuObtenuAilleurs                                                    as moyenne_tous
        from TableCours
       where cours = 'XXX'
    group by rollup(groupe);
    Regardez également du côté de CUBE et GROUPING SETS.

    Edit : d'ailleurs la syntaxe telle que vous la présentez ne devrait pas fonctionner, Oracle devrait vous réclamer un agrégat ou un group by pour la colonne nbEtuObtenuAilleurs.

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2005
    Messages : 49
    Par défaut
    Merci pour vos réponses.
    Je suis passé par 2 requêtes finalement.
    La première pour calculer les moyennes par groupe, la seconde pour tous les groupes.
    En utilisant les CASE dans mes fonctions de somme, ça m'a simplifié la requête.
    Merci pour l'astuce.
    Je vais regarder également avec GROUPING SET que je ne connaissais pas.

    Pour ta dernière remarque Waldar, tu as tout à fait raison.
    J'ai juste fait une pseudo requête pour l'idée, mais je l'avais bien géré par derrière.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2005
    Messages : 49
    Par défaut
    UPDATE :

    J'ai regardé les GROUPING SET et j'ai trouvé une meilleure solution.
    En mutualisant l'idée du CASE WHEN avec le GROUPING SET, je me retrouve avec une seule requête qui me fais la moyenne pour chaque groupe et une dernière ligne avec la moyenne générale.

    Je vous partage la grosse requête pour vous donner une idée.
    Encore merci.

    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
     
    SELECT  Controle.GRCCOD, 
              Controle.GRCCODTYPGRPCOU, 
              Controle.CTRPND,
              Controle.CTRCOTMAX,
              AVG(EtudiantControle.PNCRSUNUM) as MoyenneTous, 
              AVG (CASE   WHEN  EtudiantControle.PNCABS = 'N'
                  AND   EtudiantControle.PNCEXM = 'N'
                  AND   EtudiantControle.PNCEVADIF = 'N'
                  THEN 
                      EtudiantControle.PNCRSUNUM
                  ELSE
                      null
                  END) as CoteMoyennePresents
      FROM DSPLAN_ETUDES          PlanEtudes
      INNER JOIN DS_PLE_NOTE_CTR  EtudiantControle
      ON <conditions de jointure>
      INNER JOIN ACCONTROLE       Controle 
      ON  <conditions de jointure>
     
      WHERE Controle.intituleCours = 'XXXX'
      AND   Controle.CATCOD = 'VV'
      AND   Controle.BARTRI = 'TRIMESTREX' 
      AND   Controle.CTRNUM = 'NUMX'
      AND   PlanEtudes.NOTCOD NOT IN ('CODA', 'CODB')
      AND   PlanEtudes.PLEINDPLAOBT = 'O'
      GROUP BY GROUPING SETS ((Controle.GRCCOD, Controle.GRCCODTYPGRPCOU, Controle.CTRPND, COntrole.CTRCOTMAX), ());
    Je me suis inspiré de cette discussion avec exemple :
    http://stackoverflow.com/questions/2...ube-and-rollup

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

Discussions similaires

  1. Doublons dans une requête avec des UNION
    Par cloclo23 dans le forum Langage SQL
    Réponses: 8
    Dernier message: 12/05/2012, 13h36
  2. [MySQL] requête avec multiple And et COLLATE utf8_unicode_ci LIKE '%%"
    Par rvm31 dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 16/12/2011, 22h30
  3. optimisation de requête avec plusieurs union
    Par Smix007 dans le forum SQL
    Réponses: 11
    Dernier message: 02/04/2008, 16h59
  4. Requête avec multiple clause where
    Par pgenet dans le forum Requêtes
    Réponses: 3
    Dernier message: 07/03/2006, 13h59
  5. une requête avec plusieurs INNER JOIN, cmt faire ?
    Par elhosni dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 10/01/2006, 17h55

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