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 :

AVG + SELECT sur une colonne ?


Sujet :

SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    111
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2007
    Messages : 111
    Par défaut AVG + SELECT sur une colonne ?
    Bonjour à tous,

    une autre question me vient encore à l'esprit. Si j'effectue ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT *
    FROM MA_TABLE
    WHERE COLONNE_A > AVG(COLONNE_A)
    Le Where doit être évalué pour chaque record de ma table, mais le AVG sera-t-il aussi recalculé autant de fois ? Ou bien, Oracle est plus malin que ça ?

  2. #2
    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
    Syntaxiquement, ça ne passera pas car vous ne pouvez pas utiliser d'aggrégat dans le where.

    La requête suivante sera correcte :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT *
    FROM MA_TABLE
    WHERE COLONNE_A > (SELECT AVG(COLONNE_A) FROM MA_TABLE)
    La sous-requête ne sera bien évaluée qu'une seule fois.

  3. #3
    Expert confirmé
    Avatar de laurentschneider
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Décembre 2005
    Messages
    2 944
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Finance

    Informations forums :
    Inscription : Décembre 2005
    Messages : 2 944
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    select * from 
    (SELECT t.*, AVG(COLONNE_A) over () AVG_A
    FROM MA_TABLE)
    WHERE COLONNE_A > AVG_A
    ainsi la table MA_TABLE ne sera scannée qu'une fois !

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    111
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2007
    Messages : 111
    Par défaut
    Laurent, merci pour ta réponse éclairée

    Avec la solution proposée par Waldar, la table sera scannée plus d'une fois ?

  5. #5
    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
    Oui deux fois, une fois pour calculer la moyenne globale et une fois pour comparer celle-ci ligne à ligne.

    C'est l'avantage des fonctions analytiques !

  6. #6
    Expert confirmé
    Avatar de laurentschneider
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Décembre 2005
    Messages
    2 944
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Finance

    Informations forums :
    Inscription : Décembre 2005
    Messages : 2 944
    Par défaut
    oui, mais il faut toujours tester... parfois les résultats peuvent décevoir aussi

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    create table lsc_t1(x number primary key, a number, b varchar2(4000));
    insert into lsc_t1 select rownum,1,'xxxxxxxxxxx' from all_objects;
    insert into lsc_t1 values(0,10000,'yyy');
    exec dbms_stats.gather_table_stats(USER,'LSC_T1');
    select x,a from (select t.*, avg(a) over () avg_a from lsc_t1 t) where a>avg_a;
    select x,a from lsc_t1 where a>(select avg(a) from lsc_t1);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    select x,a from (select t.*, avg(a) over () avg_a from lsc_t1 t) 
    where a>avg_a;
             X          A
    ---------- ----------
             0      10000
    Elapsed: 00:00:00.20
    select x,a from lsc_t1 where a>(select avg(a) from lsc_t1);
             X          A
    ---------- ----------
             0      10000
    Elapsed: 00:00:00.07

    bonne soirée

Discussions similaires

  1. Un SELECT sur une même colonne avec ID différents
    Par grandthor dans le forum Requêtes
    Réponses: 1
    Dernier message: 11/08/2011, 19h21
  2. Réponses: 17
    Dernier message: 23/06/2011, 01h40
  3. Réponses: 7
    Dernier message: 10/09/2008, 15h53
  4. select distinct, sauf sur une colonne
    Par Myfred dans le forum Langage SQL
    Réponses: 5
    Dernier message: 24/04/2008, 09h40
  5. Réponses: 3
    Dernier message: 03/05/2007, 11h06

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