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 :

Requete avec un MAX


Sujet :

Requêtes MySQL

  1. #1
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2008
    Messages
    391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2008
    Messages : 391
    Points : 84
    Points
    84
    Par défaut Requete avec un MAX
    Bonjour,

    Je sais que le sujet a été traité plusieurs fois mais je n'arrive pas à l'adapter à mon cas

    Je voudrais aller chercher la ligne qui correspond au dernier id_fact du id_adh_fact mais à chaque fois il va me chercher la première ligne ; car id_adh_fact peut avoir plusieurs id_fact

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT MAX(id_fact), id_adh_fact, duree_fact, libelle_fact, date_fin_fact, nom_adh, prenom_adh, email_adh FROM facture, adherents WHERE libelle_fact!="CLOTURE" AND libelle_fact!="CONTENTIEUX" AND forfait_fact!="901" AND date_fin_fact<"'.$date_jour_en.'" AND adherents.id_adh=facture.id_adh_fact AND email_adh!="" GROUP BY id_adh_fact ORDER BY id_fact ASC
    Merci d'avance de votre aide

  2. #2
    Membre émérite
    Avatar de badaze
    Homme Profil pro
    Chef de projets info
    Inscrit en
    Septembre 2002
    Messages
    1 412
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets info
    Secteur : Transports

    Informations forums :
    Inscription : Septembre 2002
    Messages : 1 412
    Points : 2 522
    Points
    2 522
    Par défaut
    Tu devrais indiquer à quelles tables appartiennent les champs. Ca aiderait AMHA.
    Cela ne sert à rien d'optimiser quelque chose qui ne fonctionne pas.

    Mon site : www.emmella.fr

    Je recherche le manuel de l'Olivetti Logos 80B.

  3. #3
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2008
    Messages
    391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2008
    Messages : 391
    Points : 84
    Points
    84
    Par défaut
    Voici la requête avec la table a chaque fois

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT MAX(facture.id_fact), facture.id_adh_fact, facture.duree_fact, facture.libelle_fact, facture.date_fin_fact, adherents.nom_adh, adherents.prenom_adh, adherents.email_adh FROM facture, adherents WHERE facture.libelle_fact!="CLOTURE" AND facture.libelle_fact!="CONTENTIEUX" AND facture.forfait_fact!="901" AND facture.date_fin_fact<"'.$date_jour_en.'" AND adherents.id_adh=facture.id_adh_fact AND adherents.email_adh!="" GROUP BY facture.id_adh_fact ORDER BY facture.id_fact ASC

  4. #4
    Membre émérite
    Avatar de badaze
    Homme Profil pro
    Chef de projets info
    Inscrit en
    Septembre 2002
    Messages
    1 412
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets info
    Secteur : Transports

    Informations forums :
    Inscription : Septembre 2002
    Messages : 1 412
    Points : 2 522
    Points
    2 522
    Par défaut
    Essaie ça. Comme c'est fait sans pouvoir tester pas sûr que ça fonctionne, mais ça donne l'idée.

    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
     
    SELECT facture.id_fact, facture.id_adh_fact, facture.duree_fact, facture.libelle_fact, facture.date_fin_fact, adherents.nom_adh, adherents.prenom_adh, adherents.email_adh 
    FROM facture F1
    INNER JOIN
    (
    select facture.id_adh_fact, MAX(facture.id_fact) as max_id_fact
    FROM facture
    WHERE facture.libelle_fact!="CLOTURE" AND 
    facture.libelle_fact!="CONTENTIEUX" AND 
    facture.forfait_fact!="901" AND 
    facture.date_fin_fact<"'.$date_jour_en.'"
    GROUP BY facture.id_adh_fact 
    ) AS F2 ON F2.id_adh_fact = F1.id_adh_fact AND F2.max_id_fact = F1.id_fact
    INNER JOIN adherents A1 ON A1.id_adh = F1.id_adh_fact
    WHERE A1.email_adh!=""
    Cela ne sert à rien d'optimiser quelque chose qui ne fonctionne pas.

    Mon site : www.emmella.fr

    Je recherche le manuel de l'Olivetti Logos 80B.

  5. #5
    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
    Toutes les colonnes du SELECT ne faisant pas l'objet d'une fonction de groupage doivent figurer dans le GROUP BY sous peine de voir des valeurs aléatoires pour les colonnes manquantes.

    C'est ce qu'a fait Badaze
    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 !

  6. #6
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2008
    Messages
    391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2008
    Messages : 391
    Points : 84
    Points
    84
    Par défaut
    Oui mais la requete me retourne la même chose pourtant

    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
     
    SELECT f1.id_fact, f1.id_adh_fact, f1.duree_fact, f1.libelle_fact, f1.date_fin_fact, nom_adh, prenom_adh, email_adh 
    FROM facture F1
    INNER JOIN
    (
    select id_adh_fact, MAX(facture.id_fact) as max_id_fact
    FROM facture
    WHERE facture.libelle_fact!="CLOTURE" AND 
    facture.libelle_fact!="CONTENTIEUX" AND 
    facture.forfait_fact!="901" AND 
    facture.date_fin_fact<"'.$date_jour_en.'"
    GROUP BY facture.id_adh_fact 
    ) AS F2 ON F2.id_adh_fact = F1.id_adh_fact AND F2.max_id_fact = F1.id_fact
    INNER JOIN adherents A1 ON A1.id_adh = F1.id_adh_fact
    WHERE A1.email_adh!=""

  7. #7
    Membre émérite
    Avatar de badaze
    Homme Profil pro
    Chef de projets info
    Inscrit en
    Septembre 2002
    Messages
    1 412
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets info
    Secteur : Transports

    Informations forums :
    Inscription : Septembre 2002
    Messages : 1 412
    Points : 2 522
    Points
    2 522
    Par défaut
    Comme je l'ai écrit, je l'ai écrite comme ça en 5 minutes sans pouvoir faire de tests. Après on débogue en essayant chaque partie de la requête.

    Est-ce que tu l'as essayée dans phpMyAdmin ? Je vois qu'il y a une variable php. Est-ce que ce ne pourrait pas être l'exploitation des données qui ne va pas ?

    Il faudrait que tu postes la structure des tables ainsi que les données sous forme de fichier sql.
    Cela ne sert à rien d'optimiser quelque chose qui ne fonctionne pas.

    Mon site : www.emmella.fr

    Je recherche le manuel de l'Olivetti Logos 80B.

  8. #8
    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 381
    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 381
    Points : 19 065
    Points
    19 065
    Par défaut
    Salut à tous.

    Citation Envoyé par Devilju69
    Je voudrais aller chercher la ligne qui correspond au dernier id_fact du id_adh_fact mais à chaque fois il va me chercher la première ligne ; car id_adh_fact peut avoir plusieurs id_fact
    Je constate que vous n'avez toujours pas la solution à votre problème :
    Citation Envoyé par Devilju69
    Oui mais la requête me retourne la même chose pourtant
    J'ai mise ne forme votre requête afin quelle soit plus lisible.
    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
    SELECT     MAX(id_fact),
               id_adh_fact,
               duree_fact,
               libelle_fact,
               date_fin_fact,
               nom_adh,
               prenom_adh,
               email_adh
     
         FROM  facture,
               adherents
     
        WHERE  libelle_fact     != "CLOTURE"
          AND  libelle_fact     != "CONTENTIEUX"
          AND  forfait_fact     != "901"
          AND  date_fin_fact    < "'.$date_jour_en.'"
          AND  adherents.id_adh = facture.id_adh_fact
          AND  email_adh       != ""
     
     GROUP BY  id_adh_fact
     ORDER BY  id_fact ASC
    Il y a plusieurs choses qui ne vont pas :

    1) vous n'utilisez pas les jointures ?

    2) Pour extraire la ligne ayant le plus grand id_fact, vous devez rechercher son maximum.
    Pour ce faire, vous devez dans une sous-requête, rechercher par un max(id_fact) et un "group by", la plus grande valeur de votre id_fact selon vos critères.
    Puis enfin, dans la requête principale, vous devez égaliser la valeur trouvée dans la sous_requête, avec la valeur de votre sélection.

    3) la clause "where" sur le critère "!=" est source d'un problème de performance. Pourquoi ?
    Parce qu'il va balayer toutes les lignes et ne pas utiliser les index.

    Voici ce que je propose :
    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
    SELECT     f.id_fact,
               f.id_adh_fact,
               f.duree_fact,
               f.libelle_fact,
               f.date_fin_fact,
               a.nom_adh,
               a.prenom_adh,
               a.email_adh
     
          from  adherents as a
     
    inner join  facture   as f
            on  f.id_adh_fact =  a.id_adh
     
         where  a.email_adh
           and  f.id_fact = (  select  max(z.id_fact)
                                 from  facture as z
                                where  z.id_adh_fact    =  a.id_adh
                                  and  z.libelle_fact   <> "CLOTURE"
                                  and  z.libelle_fact   <> "CONTENTIEUX"
                                  and  z.forfait_fact   <> "901"
                                  and  z.date_fin_fact  <  "'.$date_jour_en.'"
                            )
     
    order by f.id_act, f.id_adh_fact;
    Comme je le suppose, vous avez plusieurs factures pour un adhérant et chaque facture est unique.
    Le fait de mettre "and f.id_fact = ( select max(z.id_fact)" va vous extraire une seule facture.

    @+
    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. Optimisation d'une requete avec fonction Max
    Par ghargamaster dans le forum Langage SQL
    Réponses: 13
    Dernier message: 28/02/2011, 09h25
  2. Requete avec clause max
    Par MASSAKA dans le forum Sybase
    Réponses: 6
    Dernier message: 09/12/2009, 13h42
  3. requetes avec clause max
    Par MASSAKA dans le forum Sybase
    Réponses: 15
    Dernier message: 03/12/2009, 17h56
  4. regroupement de tables dans une requete avec chiffre MAX
    Par db48752b dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 15/10/2009, 11h02
  5. Pb requete avec MAX
    Par Karibou dans le forum MS SQL Server
    Réponses: 11
    Dernier message: 18/08/2005, 14h05

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