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

Requêtes MySQL Discussion :

filtre sur group by


Sujet :

Requêtes MySQL

  1. #1
    Membre émérite Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Points : 2 566
    Points
    2 566
    Par défaut filtre sur group by
    Bonjour, j'ai une table de cette forme ci (pour résumer) :

    id id_fk valeur
    1 1 10
    2 1 20
    3 1 15
    4 2 10
    5 2 15
    je souhaite via une requete de sélection arriver à ceci :

    id id_fk valeur
    2 1 20
    5 2 15
    Bref, sélectionner les enregistrements correspondant au maximum des valeurs pour chaque id_fk mais j'y arrive pas

    J'avais pensé faire une sous requete avec IN mais cela m'est impossible (table identique) et j'ai également testé cette requete :

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT id_fk, max(valeur) 
    FROM ma_table
    GROUP BY id_fk

    Mais ca marche pas non plus...

    Comment puis-je faire ? Merci

  2. #2
    Membre habitué
    Inscrit en
    Juillet 2003
    Messages
    196
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 196
    Points : 165
    Points
    165
    Par défaut agrégation
    Bonjour,

    Juste un mot (sans vraiment de réponse) ton tri doit s'effectuer après ton regroupement donc il te faut le faire avec la clause HAVING.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT id_fk, valeur
    FROM ma_table
    GROUP BY id_fk
    ORDER BY valeur DESC
    LIMIT 2

  3. #3
    Membre émérite Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Points : 2 566
    Points
    2 566
    Par défaut
    Au début, je voulais faire une requete imbriquée style :

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT* FROM matable
    where id IN (
    SELECT max(id) FROM matable 
    group by id_fk
    )

    Mais ca me fait planter Apache

    Surement à cause du faite que j'utilise les 2 memes tables dans ma requete

  4. #4
    Membre éprouvé Avatar de Oishiiii
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2009
    Messages
    508
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Ain (Rhône Alpes)

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

    Informations forums :
    Inscription : Août 2009
    Messages : 508
    Points : 1 104
    Points
    1 104
    Par défaut
    Bonsoir,

    Il faut faire ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SELECT id, id_fk, valeur
    FROM ma_table
      NATURAL JOIN (
        SELECT id_fk, max(valeur) AS valeur
        FROM ma_table
        GROUP BY id_fk
      ) AS td
    Attention si vous avez deux fois la valeur Max avec un même id_fk, le résultat pourrait être différent.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    id  id_fk  valeur
    5    2     15
    6    2     15
    Si ça vous arrive, il faudra rajouter choisir la valeur que vous voulez (Min(), max(), etc..) pour la colonne id.

  5. #5
    Membre émérite Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Points : 2 566
    Points
    2 566
    Par défaut
    Nikel ca marche merci beaucoup

    Une question, pourquoi ma requete suivant n'aboutis pas ?

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    SELECT T1.cotation_id, T1.variation
    FROM cotations T1
    WHERE T1.cotation_id
    IN (
    SELECT max( T2.cotation_id )
    FROM cotations T2
    GROUP BY T2.valeur_id_fk
    )

    Cette fois ci j'ai bien "2" tables avec ma sous-requete non ?

  6. #6
    Membre éprouvé Avatar de Oishiiii
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2009
    Messages
    508
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Ain (Rhône Alpes)

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

    Informations forums :
    Inscription : Août 2009
    Messages : 508
    Points : 1 104
    Points
    1 104
    Par défaut
    J'ai utilisé une jointure naturelle puisque c'est plus beau, plus simple et plus pratique, mais vous n'avez peut-être pas tout saisi si vous n'y êtes pas habitué.
    Si je la ré-écris avec une simple jointure interne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT ma_table.id, ma_table.id_fk, ma_table.valeur
    FROM ma_table
      INNER JOIN (
        SELECT id_fk, max(valeur) AS valeur
        FROM ma_table
        GROUP BY id_fk
      ) AS td
        ON ma_table.id_fk = td.id_fk
        AND ma_table.valeur = td.valeur
    Il faut faire la jointure sur 2 colonnes, pour y ajouter la troisième (id).

    Si vous tenez vraiment au IN, essayez ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT cotation_id, variation
    FROM cotations
    WHERE (cotation_id, valeur_id_fk) IN (
      SELECT max(cotation_id), valeur_id_fk
      FROM cotations
      GROUP BY valeur_id_fk
    )

  7. #7
    Membre émérite Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Points : 2 566
    Points
    2 566
    Par défaut
    J'avoue que je suis pas habitué aux natural join...

    Pour ce qui est de votre requete IN, le résultat est le meme -> plantage

    Ci dessous, mes codes de création de la table si vous voulez tester

    Code sql : 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
     
    -- -----------------------------
    -- creation de la table cotations
    -- -----------------------------
    CREATE TABLE `cotations` (
      `cotation_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
      `valeur_id_fk` smallint(5) unsigned NOT NULL,
      `dernier` float(7,3) unsigned NOT NULL,
      `variation` float(7,3) unsigned NOT NULL,
      `ouverture` float(7,3) unsigned NOT NULL,
      `plus_haut` float(7,3) unsigned NOT NULL,
      `plus_bas` float(7,3) unsigned NOT NULL,
      `volume` int(10) unsigned NOT NULL,
      `h_cotation` int(10) unsigned NOT NULL,
      PRIMARY KEY (`cotation_id`),
      KEY `fk` (`valeur_id_fk`)
     ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
     
    INSERT INTO cotations VALUES(125905, 168, 8.210, 5.260, 8.570, 8.570, 8.200, 18036, 1273131699);
    INSERT INTO cotations VALUES(125987, 168, 8.210, 5.260, 8.570, 8.570, 8.200, 18036, 1273131727);
    INSERT INTO cotations VALUES(126068, 168, 8.210, 5.260, 8.570, 8.570, 8.200, 18036, 1273131746);
     
    INSERT INTO cotations VALUES(125906, 169, 30.000, 3.410, 29.300, 30.150, 29.300, 4414, 1273131699);
    INSERT INTO cotations VALUES(125988, 169, 30.000, 3.410, 29.300, 30.150, 29.300, 4414, 1273131727);
    INSERT INTO cotations VALUES(126151, 169, 30.000, 3.410, 29.300, 30.150, 29.300, 4414, 1273131770);

    Merci de votre aide

  8. #8
    Membre éprouvé Avatar de Oishiiii
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2009
    Messages
    508
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Ain (Rhône Alpes)

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

    Informations forums :
    Inscription : Août 2009
    Messages : 508
    Points : 1 104
    Points
    1 104
    Par défaut
    Je ne voit pas de problème.
    Quel est la version de mysql ?
    Qu'est-ce qui plante ? MySQL ?

    Edit: Ça passe très bien sur mon macbook (MySQL 5.1.31)

  9. #9
    Membre émérite Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Points : 2 566
    Points
    2 566
    Par défaut
    5.1.36-community-log
    En fait j'utilise mysql par phpMyAdmin en local avec WAMP. l'exécution de cette requete fait monter en charge Apache et finalement MySQL me lance l'erreur 2006 (MySQL server has gone away)

    EDIT: en fait c'est pas apache c'est mysqld.exe qui surchauffe

  10. #10
    Membre éprouvé Avatar de Oishiiii
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2009
    Messages
    508
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Ain (Rhône Alpes)

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

    Informations forums :
    Inscription : Août 2009
    Messages : 508
    Points : 1 104
    Points
    1 104
    Par défaut
    C'est peu-être un problème d'Apache.
    Essayez avec un client SQL, par exemple MySQL Query Browser (gratuit).
    Est-ce que la table est grosse ? (nombre de lignes / poids en Mo)
    Je ne voit rien d'autre.
    La requête est bonne, elle passe chez moi sur PostgreSQL et MySQL

  11. #11
    Membre émérite Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Points : 2 566
    Points
    2 566
    Par défaut
    Ok je vais tester ca. Ma table fait environ 8Mo je requete dessus via php (pdo). Je vous tiens au courant

  12. #12
    Membre émérite Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Points : 2 566
    Points
    2 566
    Par défaut
    En fait, en supprimant des lignes (en reprenant juste les 6 de l'insertion ci dessus, ca marche). Bizarre ma table semble pas si grosse

  13. #13
    Membre éprouvé Avatar de Oishiiii
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2009
    Messages
    508
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Ain (Rhône Alpes)

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

    Informations forums :
    Inscription : Août 2009
    Messages : 508
    Points : 1 104
    Points
    1 104
    Par défaut
    Et bien je ne peux pas l'expliquer.
    Si quelqu'un passe avec une explication ça m'intéresse aussi.
    Il vous reste toujours la table dérivée (sous-requête de la clause from)

  14. #14
    Membre émérite Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Points : 2 566
    Points
    2 566
    Par défaut
    Finalement, voici ma requete finale :

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    SELECT T1.nom, T2.dernier, T2.variation, T2.ouverture, T2.plus_haut, T2.plus_bas, T2.volume, T2.h_cotation, t2.cotation_id
    FROM valeurs T1
    INNER JOIN cotations T2 ON T1.valeur_id = T2.valeur_id_fk
    WHERE T2.cotation_id
    IN (SELECT max(T3.cotation_id)
    FROM cotations T3
    GROUP BY T3.valeur_id_fk)
    ORDER BY T2.variation DESC

    qui marche correctement alors qu'avant cela plantait...
    Seule différence (notable ?) : maintenant j'ai réduit ma sous requete à 2 enregistrements (j'ai perdu les autres comme un boulet) alors qu'avant j'avais ma sous requete qui ramenait environ 200-300 résultats. Donc est ce le nombre d'enregistrements ramenés qui peut faire ramer le IN ? Peut etre est ce une structure faire pour une enumératon de choix plus restreinte ?

    Merci de vos conseils si vous avez déjà été confrontés à un problème similaire

  15. #15
    Membre éprouvé Avatar de Oishiiii
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2009
    Messages
    508
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Ain (Rhône Alpes)

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

    Informations forums :
    Inscription : Août 2009
    Messages : 508
    Points : 1 104
    Points
    1 104
    Par défaut
    On en reviens à ce niveau:
    http://www.developpez.net/forums/d91...y/#post5193293

    Vous devez utilisez cette requête, ou l'équivalent avec NATURAL JOIN.

  16. #16
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Au sujet du plantage de la requête, est-ce que les tables sont correctement indexées ?
    Notamment les colonnes id_fk et valeur.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  17. #17
    Membre émérite Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Points : 2 566
    Points
    2 566
    Par défaut
    Citation Envoyé par Oishiiii Voir le message
    On en reviens à ce niveau:
    http://www.developpez.net/forums/d91...y/#post5193293

    Vous devez utilisez cette requête, ou l'équivalent avec NATURAL JOIN.
    Ok je vais revenir à cette méthode meme si ma requete me semblait "optimisée" mais bon je suis loin d'etre un expert SQL...

    Pour ce qui est de l'indexation, je pense que c'est correctement fait (index PRIMARY sur cotation_id et fk sur valeur_id_fk indexée). Voir ci dessous :

    Code sql : 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
     
    -- -----------------------------
    -- creation de la table cotations
    -- -----------------------------
    CREATE TABLE `cotations` (
      `cotation_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
      `valeur_id_fk` smallint(5) unsigned NOT NULL,
      `dernier` float(7,3) unsigned NOT NULL,
      `variation` float(7,3) unsigned NOT NULL,
      `ouverture` float(7,3) unsigned NOT NULL,
      `plus_haut` float(7,3) unsigned NOT NULL,
      `plus_bas` float(7,3) unsigned NOT NULL,
      `volume` int(10) unsigned NOT NULL,
      `h_cotation` int(10) unsigned NOT NULL,
      PRIMARY KEY (`cotation_id`),
      KEY `fk` (`valeur_id_fk`),
      CONSTRAINT `cotations_ibfk_1` FOREIGN KEY (`valeur_id_fk`) REFERENCES `valeurs` (`valeur_id`) ON DELETE CASCADE
    ) ENGINE=InnoDB AUTO_INCREMENT=201375 DEFAULT CHARSET=latin1;
     
    -- -----------------------------
    -- creation de la table valeurs
    -- -----------------------------
    CREATE TABLE `valeurs` (
      `valeur_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
      `cle` varchar(100) NOT NULL,
      `nom` varchar(100) NOT NULL,
      `jour` date NOT NULL,
      PRIMARY KEY (`valeur_id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=381 DEFAULT CHARSET=latin1;

Discussions similaires

  1. [AC-2013] filtre par groupe d'options sur un formulaire
    Par abdoudiaw dans le forum VBA Access
    Réponses: 4
    Dernier message: 17/09/2013, 16h27
  2. [SP-2010] Filtre sur groupe utilisateurs
    Par redmonster dans le forum SharePoint
    Réponses: 14
    Dernier message: 01/02/2012, 16h08
  3. [2008] Problème de somme après filtre sur groupe
    Par tonitoBI dans le forum SSRS
    Réponses: 1
    Dernier message: 02/11/2011, 14h37
  4. Filtre sur une base Paradox
    Par mika dans le forum Bases de données
    Réponses: 2
    Dernier message: 11/03/2004, 11h51
  5. [Sybase] filtre sur caractères spéciaux
    Par montelieri dans le forum Sybase
    Réponses: 4
    Dernier message: 07/04/2003, 16h49

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