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 :

Requête imbriquée : problème de group by


Sujet :

Requêtes MySQL

  1. #1
    Nouveau membre du Club
    Inscrit en
    Février 2003
    Messages
    51
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 51
    Points : 39
    Points
    39
    Par défaut Requête imbriquée : problème de group by
    Bonjour,
    J'ai une table dans laquelle je stocke les alimentations en eaux de plusieurs aquariums avec une date de début et de fin.
    J'essaye de construire une requête qui me donne par aquarium la date de fin la plus éloignée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select * from Alimente a1 where a1.Fin_Alimente = (select max(a2.Fin_Alimente) from Alimente a2 where a2.ID_Alimente = a1.ID_Alimente group by a2.ID_Aquarium )
    avec la jointure, le group by ne rempli pas son rôle...
    je sèche...merci de votre aide

  2. #2
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    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 080
    Points : 30 795
    Points
    30 795
    Par défaut
    Il y a bien en effet un problème de group by... mais parce qu'il est gêné par la jointure.
    La jointure doit en effet être effectuée sur ID_Aquarium et non sur ID_Alimente qui doit sans doute être la clé de la table Alimente (c'est pour cela qu'il faut donner la structure des tables quand on expose un problème).
    La bonne requête serait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    select  *
    from    Alimente    a1 
    where   a1.Fin_Alimente = 
            (   select  max(a2.Fin_Alimente) 
                from    Alimente    a2 
                where   a2.ID_Aquarium = a1.ID_Aquarium 
            --  group by a2.ID_Aquarium
            )
    ;
    Tu remarqueras que j'ai mis le group by en commentaire, parce qu'il est implicite.
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  3. #3
    Nouveau membre du Club
    Inscrit en
    Février 2003
    Messages
    51
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 51
    Points : 39
    Points
    39
    Par défaut
    Le résultat est toujours identique, à savoir plusieurs lignes retournées par aquarium.
    ID_Alimente est bien la clé et ID_Aquarium une clé étrangère.
    Merci pour ton aide.

  4. #4
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    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 080
    Points : 30 795
    Points
    30 795
    Par défaut
    S'il y a plusieurs lignes retournées par aquarium, c'est surement qu'elles ont la même date Fin_Alimente.
    ... si c'est bien cette requête que tu utilises.
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  5. #5
    Nouveau membre du Club
    Inscrit en
    Février 2003
    Messages
    51
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 51
    Points : 39
    Points
    39
    Par défaut
    Oui tu as raison, je n'avais pas fait attention à la date. Je vais m'en arranger du coup !
    Merci

  6. #6
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 380
    Points : 19 062
    Points
    19 062
    Par défaut
    Salut Popysan.

    Si vous aviez commencé par nous donner le descriptif des tables, un jeu d'essai et le résultat final que vous désirez obtenir, cela nous aurait faciliter la vie !

    D'après ce que j'ai compris de la nature de votre problème, vous avez des doublons en ce qui concerne la date "fin_alimente".
    C'est pourquoi, la sélection par la valeur maximale ne va pas vous retourner une et une seule ligne.

    Dans votre exemple, le group by ne sert à rien car le doublon se trouve justement sur la date "fin_alimente" que vous sélectionnez.

    En fait, vous avez un double critère.
    1) récupérer la plus grande valeur de la date "fin_alimente".
    2) et sur ce critère, récupérer la plus grande valeur de la colonne "id_alimente".

    C'est sur la colonne "id_alimente" que devra se faire votre sélection.
    J'ai pris la dernière valeur de cette colonne. Si vous préférez la première, on peut changer le critère de sélection.

    Voici le résultat attendu. J'ai décomposé le problème en plusieurs parties afin de bien visualiser les résultats.
    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
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    --------------
    SET AUTOCOMMIT = 0
    --------------
     
    --------------
    START TRANSACTION
    --------------
     
    --------------
    DROP DATABASE IF EXISTS `base`
    --------------
     
    --------------
    CREATE DATABASE `base`
        DEFAULT CHARACTER SET `latin1`
        DEFAULT COLLATE       `latin1_general_ci`
    --------------
     
    --------------
    DROP TABLE IF EXISTS `alimente`
    --------------
     
    --------------
    CREATE TABLE `alimente`
    ( `id_alimente`     integer unsigned NOT NULL auto_increment primary key,
      `id_aquarium`     integer unsigned NOT NULL,
      `fin_alimente`    date             NOT NULL
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED
    --------------
     
    --------------
    insert into `alimente` (`id_aquarium`,`fin_alimente`) values
      (1,'2016-08-01'),(1,'2016-08-02'),(1,'2016-08-23'),(1,'2016-08-15'),(1,'2016-08-23'),(1,'2016-08-18'),
      (2,'2016-07-21'),(2,'2016-07-15'),(2,'2016-07-21'),(2,'2016-07-18'),(2,'2016-07-14')
    --------------
     
    --------------
    select * from alimente
    --------------
     
    +-------------+-------------+--------------+
    | id_alimente | id_aquarium | fin_alimente |
    +-------------+-------------+--------------+
    |           1 |           1 | 2016-08-01   |
    |           2 |           1 | 2016-08-02   |
    |           3 |           1 | 2016-08-23   |
    |           4 |           1 | 2016-08-15   |
    |           5 |           1 | 2016-08-23   |
    |           6 |           1 | 2016-08-18   |
    |           7 |           2 | 2016-07-21   |
    |           8 |           2 | 2016-07-15   |
    |           9 |           2 | 2016-07-21   |
    |          10 |           2 | 2016-07-18   |
    |          11 |           2 | 2016-07-14   |
    +-------------+-------------+--------------+
    --------------
    select  max(t2.fin_alimente) as fin_alimente
        from  alimente as t2
    group by  t2.id_aquarium
    --------------
     
    +--------------+
    | fin_alimente |
    +--------------+
    | 2016-08-23   |
    | 2016-07-21   |
    +--------------+
    --------------
    select  *
      from  alimente as t1
     where  fin_alimente = (
        select  max(t2.fin_alimente) as fin_alimente
          from  alimente as t2
         where  t2.id_aquarium = t1.id_aquarium
    )
    --------------
     
    +-------------+-------------+--------------+
    | id_alimente | id_aquarium | fin_alimente |
    +-------------+-------------+--------------+
    |           3 |           1 | 2016-08-23   |
    |           5 |           1 | 2016-08-23   |
    |           7 |           2 | 2016-07-21   |
    |           9 |           2 | 2016-07-21   |
    +-------------+-------------+--------------+
    --------------
    select *
    from alimente as t1
     
    where id_alimente = (
     
             select    t2.id_alimente
               from    alimente as t2
    left outer join    alimente as t3
                 on    t3.id_aquarium = t2.id_aquarium
                and (( t3.fin_alimente > t2.fin_alimente )
                 or  ((t3.fin_alimente = t2.fin_alimente)
                and   (t3.id_alimente > t2.id_alimente  )))
              where    t3.id_alimente is null
                and    t2.id_aquarium = t1.id_aquarium
           group by    t3.id_aquarium
    )
    --------------
     
    +-------------+-------------+--------------+
    | id_alimente | id_aquarium | fin_alimente |
    +-------------+-------------+--------------+
    |           5 |           1 | 2016-08-23   |
    |           9 |           2 | 2016-07-21   |
    +-------------+-------------+--------------+
    --------------
    select a1.*
    from            alimente as a1
     
    left outer join alimente as a2  on a2.id_aquarium = a1.id_aquarium and a2.fin_alimente > a1.fin_alimente
    left outer join alimente as a3  on a3.id_aquarium = a1.id_aquarium and a3.fin_alimente = a1.fin_alimente and a3.id_alimente > a1.id_alimente
     
    where a2.fin_alimente is null and a3.id_alimente is null
    --------------
     
    +-------------+-------------+--------------+
    | id_alimente | id_aquarium | fin_alimente |
    +-------------+-------------+--------------+
    |           5 |           1 | 2016-08-23   |
    |           9 |           2 | 2016-07-21   |
    +-------------+-------------+--------------+
    --------------
    COMMIT
    --------------
     
    --------------
    SET AUTOCOMMIT = 1
    --------------
     
    Appuyez sur une touche pour continuer...
    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

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

Discussions similaires

  1. MYSQL => requête imbriquée = problème
    Par ambigua dans le forum Langage SQL
    Réponses: 2
    Dernier message: 07/04/2012, 18h09
  2. Problème de requêtes sans requêtes imbriquées
    Par toddy_101 dans le forum Requêtes
    Réponses: 3
    Dernier message: 29/12/2006, 10h27
  3. Problème Requête imbriquée
    Par EddieN dans le forum Langage SQL
    Réponses: 5
    Dernier message: 11/10/2006, 07h52
  4. Pb de COUNT et GROUP BY simple mais sans requête imbriquées
    Par vanquish dans le forum Langage SQL
    Réponses: 3
    Dernier message: 22/10/2004, 09h45
  5. problème avec une requête imbriquée
    Par jaimepasteevy dans le forum Langage SQL
    Réponses: 13
    Dernier message: 05/12/2003, 10h29

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