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

SQLite Discussion :

Requête avec max(), group by et having. je m'y perds


Sujet :

SQLite

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 14
    Points : 9
    Points
    9
    Par défaut Requête avec max(), group by et having. je m'y perds
    salut à tous,
    j'ai une table "table" de ce type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    id   | version       |       valeur
     1    |    100         |    bla bla bla
     1    |    101         |    bla bla bla
     1    |    102         |    bla bla bla
     2    |    100         |    bla bla bla
     2    |    101         |    bla bla bla
     2    |    102         |     bla bla bla
     2    |    103         |    bla bla bla
    etc...
    je souhaite que ma requête dans la table me renvoie une ligne pour chaque ID, correspondant à la version la plus haute pour chaque ID, comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ligne 1 : 1    -->    102         -->    bla bla bla
    ligne 2 : 2    -->    103         -->    bla bla bla
    etc...
    Ceci fonctionne et me renvoie ce que je veux :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT id, version, valeur FROM table AS det WHERE EXISTS
            (SELECT  1
                FROM    table  AS  grp
                WHERE det.id   = grp.id
                GROUP BY grp.id
                HAVING  det.version = MAX(grp.version)
            )
    Mais c'est très lent !!!

    alors j'ai essayé comme ça, mais ça ne marche pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT id, version, valeur FROM table 
      GROUP BY id 
      HAVING version = MAX(version)
    quelqu'un a une idée ?

  2. #2
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 103
    Points : 28 394
    Points
    28 394
    Par défaut
    As-tu un index sur la colonne id ?

    Tu peux aussi l'écrire en utilisant une table dérivée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SELECT  det.id
        ,   det.version
        ,   det.valeur 
    FROM    TABLE AS det
        INNER JOIN
            (   SELECT  id
                    ,   MAX(version)    AS max_version
                FROM    TABLE
                GROUP BY grp.id
            )   AS  grp
        ON  det.id   = grp.id
        AND det.version = max_version
    Compare les plans d'exécution pour voir lequel est le meilleur.

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Février 2005
    Messages
    94
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 94
    Points : 98
    Points
    98
    Par défaut
    Est-ce que ça marche si tu fais comme ça ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT id, MAX(version), valeur
    FROM TABLE
    GROUP BY id

  4. #4
    Membre actif

    Inscrit en
    Décembre 2004
    Messages
    169
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 169
    Points : 225
    Points
    225
    Par défaut
    Non la requête
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT id, MAX(version), valeur
    FROM TABLE
    GROUP BY id
    ne retourne pas les bons éléments.

    Voici une table de test :
    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
    drop table if exists version;
    create table version (id int, v int, t text);
    insert into version values (1,101,'aaa');
    insert into version values (1,102,'bbb');
    insert into version values (1,104,'ccc');
     
    insert into version values (2,201,'ddd');
    insert into version values (2,202,'eee');
    insert into version values (2,203,'aaa');
    insert into version values (2,205,'fff');
     
    insert into version values (3,301,'ggg');
    insert into version values (3,308,'kkk');
    insert into version values (3,303,'hhh');
    insert into version values (3,304,'iii');
    Voici le résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    sqlite> select id, max(v), t from version group by id;
    1       104     ccc
    2       205     fff
    3       308     iii
    On voit alors que "iii" n'est pas le texte que doit retourner la requête, c'est juste le dernier texte associé à l'id 3.

    La requête d'al1_v24 est la bonne.
    On peut également l'écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    select id, version, valeur from 'table', (
    	select id as max_id, max(version) as max_version 
    	from 'table' group by id
    ) m
    where table.id  = m.max_id and table.version = m.max_version;
    Pour accélérer les traitements, il te suffit de créer un index sur les colonnes id et version.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    create index idx_id_version on 'table' (id, version);
    Comme ces colonnes sont utilisées ensemble dans la requête, cela donnera un résultat avec une vitesse grand V.

    a+

Discussions similaires

  1. Formulation d'une requête mysql avec max & group by
    Par Didier100 dans le forum Requêtes
    Réponses: 4
    Dernier message: 23/09/2010, 16h37
  2. Requête avec MAX et GROUP BY (2)
    Par kmarcel dans le forum Langage SQL
    Réponses: 2
    Dernier message: 05/02/2008, 12h55
  3. requête avec MAX et GROUP BY
    Par arcane dans le forum Langage SQL
    Réponses: 8
    Dernier message: 30/01/2008, 13h21
  4. Requête avec max date et champs correspondants
    Par sl1980 dans le forum Requêtes et SQL.
    Réponses: 3
    Dernier message: 23/09/2007, 00h01
  5. Requête avec MAX et COUNT
    Par arno a. dans le forum PostgreSQL
    Réponses: 2
    Dernier message: 16/04/2007, 14h02

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