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 :

GROUP BY et SELECT *


Sujet :

SQL Oracle

  1. #1
    Membre averti
    Inscrit en
    Avril 2005
    Messages
    32
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 32
    Par défaut GROUP BY et SELECT *
    Bonjour à tous ,

    Est-il possible de faire un select * avec une clause group by ?

    Comme par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM Table1 GROUP BY Champ1
    Ou doit-on spécifier tous les champs dans le Select ?

    Cordialement.

  2. #2
    Membre chevronné Avatar de chrifo
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    444
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 444
    Par défaut
    Bonjour,
    Le problème n'est pas dans le select mais dans le group by, qui va vous demander plus de colonnes, selon les données de la table.
    Pourquoi ne pas tout simplement faire un "distinct" ?

  3. #3
    Membre averti
    Inscrit en
    Avril 2005
    Messages
    32
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 32
    Par défaut
    Si j'utilise distinct je suis obligé d'écrire tous les champs dans ma requête comme par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Select distinct Champ1, Champ2 ... champN
    Donc le '*' ne fonctionnera pas d'avantage non ?

  4. #4
    Membre Expert Avatar de pacmann
    Homme Profil pro
    Consulté Oracle
    Inscrit en
    Juin 2004
    Messages
    1 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consulté Oracle
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Par défaut
    Salut !

    Qu'essaies-tu d'obtenir ?
    GROUP BY te permet de définir des groupes selon un certain critère (égalité sur champ1), afin de pouvoir appliquer des fonctions d'aggrégat sur ce groupe.
    => une seule ligne t'es retournée par valeur possible de champ1

    Si tu demandes le champ2, quelle valeur va-t-on bien pouvoir te retourner, vu que ce n'est pas la même pour toutes les lignes du groupe ?

    Si ce que tu veux, c'est obtenir les résultats d'agrégats reportés sur chaque ligne, essaie les fonction analytiques : OVER(PARTITION BY champ1)

  5. #5
    Membre chevronné Avatar de chrifo
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    444
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 444
    Par défaut
    Citation Envoyé par guiph Voir le message
    Donc le '*' ne fonctionnera pas d'avantage non ?
    Sisi, ça fonctionnera.

    Attention : distinct et group by n'ont rien à voir, évitez d'utiliser un regroupement lorsque cela est inutile.

  6. #6
    Membre averti
    Inscrit en
    Avril 2005
    Messages
    32
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 32
    Par défaut
    Citation Envoyé par pacmann Voir le message
    Salut !

    Qu'essaies-tu d'obtenir ?
    GROUP BY te permet de définir des groupes selon un certain critère (égalité sur champ1), afin de pouvoir appliquer des fonctions d'aggrégat sur ce groupe.
    => une seule ligne t'es retournée par valeur possible de champ1

    Si tu demandes le champ2, quelle valeur va-t-on bien pouvoir te retourner, vu que ce n'est pas la même pour toutes les lignes du groupe ?

    Si ce que tu veux, c'est obtenir les résultats d'agrégats reportés sur chaque ligne, essaie les fonction analytiques : OVER(PARTITION BY champ1)
    Oui en fait je souhaite prendre une seule ligne par doublon, peut importe la valeurs des autres champs mais il faut que j'affiche une ligne. La première par exemple.

    Je ne sais pas si j'ai été bien clair

    Par contre je ne connais pas du tout les fonctions analytiques ...

  7. #7
    Membre chevronné Avatar de chrifo
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    444
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 444
    Par défaut
    De toutes manières avec les fonctions analytiques vous allez devoir traiter chaque champ.
    Peut-être l'utilisation du rownum peut vous être utile :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    select Table1.* 
    from  
      (select rownum numrow, Table1.* from Table1) Table1
      inner join (SELECT min(rownum) numrow, Champ1 FROM Table1 group by Champ1) T1 on Table1.numrow = T1.numrow and Table1.Champ1 = T1.Champ1

  8. #8
    Membre averti
    Inscrit en
    Avril 2005
    Messages
    32
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 32
    Par défaut
    Merci pour vos bonnes idées

  9. #9
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par guiph Voir le message
    Est-il possible de faire un select * avec une clause group by ?
    Par principe, ce n'est jamais une bonne idée de faire un select * et ça ne coûte pas plus cher d'écrire tous les champs, même si ça peut faire lourd.
    Une modification de ta table et ta requète peut te renvoyer des résultats bizarres.
    Et pour trouver la source de ce genre d'erreurs, c'est plutôt chronophage.

  10. #10
    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
    Citation Envoyé par chrifo Voir le message
    De toutes manières avec les fonctions analytiques vous allez devoir traiter chaque champ.
    Peut-être l'utilisation du rownum peut vous être utile :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    select Table1.* 
    from  
      (select rownum numrow, Table1.* from Table1) Table1
    inner join (SELECT min(rownum) numrow, Champ1 FROM Table1
      group by Champ1) T1 
    on Table1.numrow = T1.numrow and Table1.Champ1 = T1.Champ1
    Vraiment intéressant comme approche.

    Bon, tu auras quand même "rownum" dans la sélection. Donc, le * ne fonctionne pas, il te faudrait un "* mais pas rownum".

    Aussi tu t'es pas sur que le rownum de T1 corresponde au rownum de Table1, suivant le plan rownum pourrait ne pas correspondre aux même lignes.

    Pour éviter ceci j'utiliserais donc

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    select * from emp where (empno,deptno) in 
      (select max(empno),deptno from emp group by deptno)
    Avec EMPNO clé primaire

  11. #11
    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
    Citation Envoyé par Jerome_Mtl Voir le message
    Par principe, ce n'est jamais une bonne idée de faire un select *
    Tout à faire d'accord, ce n'est en principe pas une bonne idée, surtout quand on fait ça par paresse

  12. #12
    Membre chevronné Avatar de chrifo
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    444
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 444
    Par défaut
    Citation Envoyé par laurentschneider Voir le message
    Aussi tu t'es pas sur que le rownum de T1 corresponde au rownum de Table1, suivant le plan rownum pourrait ne pas correspondre aux même lignes.
    Arghh, je te crois sur parole et mes noms d'alias étaient maladroits, mais je pensais que le fait de "pré-sélectionner" mes rownums comme je l'ai fait dans les deux sous-requêtes me mettrait à l'abri du problème.

  13. #13
    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
    bon, je vois, il va falloir te trouver une démo ...

    excuse-moi si c'est un peu brouillon, c'était pas si simple de trouver un cas où ca ne marche pas.

    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
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    SQL> col x for a10 tru
    SQL> col x_1 for a10 tru
    SQL> col z for a10 tru
    SQL> create table t(x varchar2(4000), y number, z varchar2(4000))
    Table created.
    SQL> insert into t values (lpad('c',4000,'c'), 4, lpad('z',4000,'z'))
    1 row created.
    SQL> insert into t values (lpad('c',4000,'c'), 4, lpad('z',4000,'z'))
    1 row created.
    SQL> insert into t values (lpad('a',4000,'a'), 1, lpad('z',4000,'z'))
    1 row created.
    SQL> insert into t values (lpad('a',4000,'a'), 2, lpad('z',4000,'z'))
    1 row created.
    SQL> insert into t values (lpad('b',4000,'b'), 3, lpad('z',4000,'z'))
    1 row created.
    SQL> insert into t values (lpad('b',4000,'b'), 4, lpad('z',4000,'z'))
    1 row created.
    SQL> insert into t values (lpad('b',4000,'b'), 5, lpad('z',4000,'z'))
    1 row created.
    SQL> insert into t values (lpad('b',4000,'b'), 6, lpad('z',4000,'z'))
    1 row created.
    SQL> insert into t values (lpad('b',4000,'b'), 7, lpad('z',4000,'z'))
    1 row created.
    SQL> insert into t values (lpad('b',4000,'b'), 8, lpad('z',4000,'z'))
    1 row created.
    SQL> insert into t values (lpad('b',4000,'b'), 9, lpad('z',4000,'z'))
    1 row created.
    SQL> insert into t values (lpad('b',4000,'b'), 10, lpad('z',4000,'z'))
    1 row created.
    SQL> insert into t values (lpad('b',4000,'b'), 11, lpad('z',4000,'z'))
    1 row created.
    SQL> commit
    Commit complete.
    SQL> create or replace view v as select x,y,z from t where y<15
    View created.
    SQL> select rownum, v.* from v
     
        ROWNUM X                   Y Z         
    ---------- ---------- ---------- ----------
             1 cccccccccc          4 zzzzzzzzzz
             2 cccccccccc          4 zzzzzzzzzz
             3 aaaaaaaaaa          1 zzzzzzzzzz
             4 aaaaaaaaaa          2 zzzzzzzzzz
             5 bbbbbbbbbb          3 zzzzzzzzzz
             6 bbbbbbbbbb          4 zzzzzzzzzz
             7 bbbbbbbbbb          6 zzzzzzzzzz
             8 bbbbbbbbbb          8 zzzzzzzzzz
             9 bbbbbbbbbb          7 zzzzzzzzzz
            10 bbbbbbbbbb          5 zzzzzzzzzz
            11 bbbbbbbbbb          9 zzzzzzzzzz
            12 bbbbbbbbbb         10 zzzzzzzzzz
            13 bbbbbbbbbb         11 zzzzzzzzzz
     
     
    13 rows selected.
    SQL> select x,min(rownum) from v group by x
     
    X          MIN(ROWNUM)
    ---------- -----------
    cccccccccc           1
    bbbbbbbbbb           5
    aaaaaaaaaa           3
     
     
    3 rows selected.
    SQL> create index i on t(y,x) compute statistics
    Index created.
    SQL> analyze table t compute statistics
    Table analyzed.
    SQL> select rownum, v.* from v
     
        ROWNUM X                   Y Z         
    ---------- ---------- ---------- ----------
             1 cccccccccc          4 zzzzzzzzzz
             2 cccccccccc          4 zzzzzzzzzz
             3 aaaaaaaaaa          1 zzzzzzzzzz
             4 aaaaaaaaaa          2 zzzzzzzzzz
             5 bbbbbbbbbb          3 zzzzzzzzzz
             6 bbbbbbbbbb          4 zzzzzzzzzz
             7 bbbbbbbbbb          6 zzzzzzzzzz
             8 bbbbbbbbbb          8 zzzzzzzzzz
             9 bbbbbbbbbb          7 zzzzzzzzzz
            10 bbbbbbbbbb          5 zzzzzzzzzz
            11 bbbbbbbbbb          9 zzzzzzzzzz
            12 bbbbbbbbbb         10 zzzzzzzzzz
            13 bbbbbbbbbb         11 zzzzzzzzzz
     
     
    13 rows selected.
    SQL> select min(rownum),x from v group by x
     
    MIN(ROWNUM) X         
    ----------- ----------
              3 bbbbbbbbbb
              5 cccccccccc
              1 aaaaaaaaaa
     
     
    3 rows selected.
    SQL> SELECT * 
    FROM  
      (SELECT rownum numrow, v.* FROM v) Table1
      INNER JOIN (SELECT min(rownum) numrow, x FROM v GROUP BY x) T1 
      ON Table1.numrow = T1.numrow AND Table1.x = T1.x
    no rows selected.
    SQL> drop index i
    Index dropped.
    SQL> SELECT * 
    FROM  
      (SELECT rownum numrow, v.* FROM v) Table1
      INNER JOIN (SELECT min(rownum) numrow, x FROM v GROUP BY x) T1 
      ON Table1.numrow = T1.numrow AND Table1.x = T1.x
     
        NUMROW X                   Y Z            NUMROW_1 X_1       
    ---------- ---------- ---------- ---------- ---------- ----------
             1 cccccccccc          4 zzzzzzzzzz          1 cccccccccc
             3 aaaaaaaaaa          1 zzzzzzzzzz          3 aaaaaaaaaa
             5 bbbbbbbbbb          3 zzzzzzzzzz          5 bbbbbbbbbb
     
     
    3 rows selected.

  14. #14
    Membre chevronné Avatar de chrifo
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    444
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 444
    Par défaut
    Ok je vois mieux le problème, effectivement c'est un peu difficile à reproduire mais le problème est bien là, donc méthode à éviter.

    Merci beaucoup pour la démo !

Discussions similaires

  1. Problème SELECT, CASE et Group by
    Par Royd938 dans le forum MS SQL Server
    Réponses: 9
    Dernier message: 03/10/2014, 07h41
  2. Petite interrogation....SELECT ... GROUP BY
    Par zevince dans le forum PostgreSQL
    Réponses: 6
    Dernier message: 15/04/2013, 13h52
  3. selection avec group by mais ne garder que ...
    Par Larson dans le forum Langage SQL
    Réponses: 13
    Dernier message: 22/06/2005, 17h23
  4. Faire un Select v1 sans mettre v1 dans Group By
    Par faayy dans le forum Langage SQL
    Réponses: 6
    Dernier message: 12/05/2005, 09h28
  5. Selection de Groupes ki ne sont pas sous groupes...
    Par superdada dans le forum Langage SQL
    Réponses: 2
    Dernier message: 23/07/2003, 14h42

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