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 :

classement de vendeurs en fonction du nombre de leurs ventes + extractions de dates


Sujet :

Requêtes MySQL

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 56
    Points : 36
    Points
    36
    Par défaut classement de vendeurs en fonction du nombre de leurs ventes + extractions de dates
    Re-Bonjour, j'ai deux nouveaux problèmes que j'ai pourtant essayé d'apurer au maximum sans succès.... (faq, forums, cours universitaires.....oops) :

    --> Alors voilà la première requête en question : "Afficher les vendeurs ayant réalisé plus de 2 ventes, par ordre de nombre de vente croissant"

    J'ai une table vendeur, une table clients et une table commande - cette dernière étant liée aux 2 premières via l'ID des vendeurs et des clients (respectivement "novdeur" et "nocli")

    J'ai proposé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    select commande.novdeur as "No Vdeur", vendeur.nomvdeur as "Vdeur", count(nocde) as "Nb Cde" 
    from commande, vendeur 
    where count(nocde)>1 and commande.novdeur=vendeur.novdeur 
    group by commande.novdeur 
    order by count(nocde) desc;
    Résultat : tout fonctionne lorsque la ligne que j'ai indiquée en gras n'y est pas, mais je n'ai pas les informations voulues du coup... svez-vous où est mon erreur ? (apparement c l'enchainement "where count..." qui pose probleme, et c pareil avec "and count...")

    --> La deuxième requête est la suivante :"Afficher pour chaque commande du mois d’octobre 2004, les noms et prénoms des clients et des vendeurs"

    Alors là on utilise les mêmes tables que pour la requête ci-dessus.

    J'ai bien compris que j'allais devoir utiliser la fonction EXTRACT FROM mais rien n'y fait, ça ne fonctionne pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT datecde, nocde, nomvdeur, pnomvdeur, nomcli, pnomcli, 
    FROM commande, clientele, vendeur
    WHERE commande.nocli=clientele.nocli
    AND commande.novdeur=vendeur.novdeur
    AND EXTRACT(YEAR FROM datecde)=2004
    AND EXTRACT(MONTH FROM datecde)=10;

    Au cas où, voici mes tables :
    Clientele (NoCli, Societe, NomCli, PnomCli, RueCli, CpCli, VilleCli)

    Vendeur (Novdeur, NomVdeur, PnomVdeur, DateEmbauchVdeur, VilleTravailVdeur, SalaireMensuelVdeur, TauxCommissionVdeur, Cadre) Rem : Cadre est un booléen.

    Commande (NoCde, DateCde, Facture, #NoVdeur, #NoCli)



    Merci d'avance pour vos réponses (niveau débutant... ça se voit je pense... mais bon, sur 35 requêtes je ne vous aurais appelé à l'aide que 3 fois... pas mal non ?

    fanico11

  2. #2
    Expert confirmé Avatar de Cybher
    Homme Profil pro
    Consultant réseaux et sécurité
    Inscrit en
    Mai 2005
    Messages
    3 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Consultant réseaux et sécurité
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 281
    Points : 4 644
    Points
    4 644
    Par défaut
    salut,

    pour la premiere question, regarde comment utiliser la clause 'having'

    pour la seconde, pourquoi tu fais un extract(year) pour le mois?

    dernier conseil, essaie d'utiliser les jointures normalisées (JOIN)

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 56
    Points : 36
    Points
    36
    Par défaut
    Citation Envoyé par Cybher Voir le message
    salut,

    pour la premiere question, regarde comment utiliser la clause 'having'

    pour la seconde, pourquoi tu fais un extract(year) pour le mois?

    dernier conseil, essaie d'utiliser les jointures normalisées (JOIN)
    --> Pour la première requête, j'ai suivi votre conseil et utilisé la clause HAVING ce qui me donne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    select commande.novdeur as "No Vdeur", vendeur.nomvdeur as "Vdeur", count(nocde) as "Nb Cde" 
    from commande, vendeur 
    where commande.novdeur=vendeur.novdeur 
    having count(nocde)>1 
    group by commande.novdeur 
    order by count(nocde) desc;
    et cela ne marche toujours pas, maintenant il semble que ce soit l'enchainement "order by count(...)" qui pose problème...

    --> Pour ma deuxième requête c'était une erreur de recopie, mais même avec MONTH cela ne marche pas...
    Je vais tenter d'utiliser les JOIN mais à mon avis cela ne reglera pas le problème...

    quelqu'un a-t-il une autre solution ? où ai-je fait une erreur??

    en tout cas merci, j'ai appris à utiliser HAVING au lieu de WHERE quand il le faut...

    fanico11

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 56
    Points : 36
    Points
    36
    Par défaut
    Je ne comprends pas l'utilisation de JOIN, si on pouvait conserver les jointures telles que je les ai mises ce serait mieux pour moi...

    j'ai par exemple essayé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    SELECT datecde, nocde, nomvdeur, pnomvdeur, nomcli, pnomcli 
    FROM commande co 
    full outer join clientele c on co.novdeur=c.novdeur 
    WHERE EXTRACT(YEAR FROM datecde)=2004 
       AND EXTRACT(MONTH FROM datecde)=10 
    UNION 
    SELECT datecde, nocde, nomvdeur, pnomvdeur, nomcli, pnomcli 
    FROM commande co 
    full outer join clientele c on co.nocli=c.nocli 
    WHERE EXTRACT(YEAR FROM datecde)=2004 
       AND EXTRACT(MONTH FROM datecde)=10;
    et rien ne marche (ça ne marche pas non plus si je n'utilise pas les raccourcis "co" et "c")... je ne comprends plus...

  5. #5
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    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 801
    Points : 34 063
    Points
    34 063
    Billets dans le blog
    14
    Par défaut
    Tu fais l'union de deux sous-requêtes identiques ! C'est inutile !

    Je suppose que nomvendeur vient de la table vendeur mais elle ne figure plus dans ta requête.

    Dire "ça marche pas" est un constat. Nous décrire les symptômes (message d'erreur, résultat obtenu par rapport au résultat attendu...), c'est plus productif pour qu'on puisse t'aider et ça peut même t'aider à comprendre tes erreurs.

    Je ne comprends pas l'utilisation de JOIN, si on pouvait conserver les jointures telles que je les ai mises ce serait mieux pour moi...
    Apparemment, tu les as à peu près comprises puisque que tu les as correctement écrites. C'est la syntaxe normalisée depuis 1992 alors il est temps de s'y mettre, même si tes profs t'ont appris l'ancienne syntaxe ; ce sont eux qui retardent de 18 ans !
    Pour plus d'info, voir le cours de SQLPro.

    Revenons au problème posé...
    "Afficher les vendeurs ayant réalisé plus de 2 ventes, par ordre de nombre de vente croissant"
    A priori, on n'a ici pas besoin des clients. On fait donc seulement une jointure entre les commandes et les vendeurs. Et comme on veut seulement les vendeurs ayant réalisé plus de deux commandes, on peut se contenter d'une jointure interne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT v.novdeur, v.nomvdeur, v.pnomvendeur,
      COUNT(co.nocde) As Nombre_commandes
    FROM vendeur AS v
    INNER JOIN commande AS co ON co.novdeur = v.novdeur
    WHERE EXTRACT(YEAR FROM co.datecde) = 2004
      AND EXTRACT(MONTH FROM co.datecde) = 10
    GROUP BY v.novdeur, v.nomvdeur
    HAVING COUNT(co.nocde) > 2
    ORDER BY COUNT(co.nocde)
    Au passage, tu vois que j'utilise les alias de tables partout pour lever les ambiguïtés éventuelles entre des colonnes portant le même nom dans différentes tables.

    "Afficher pour chaque commande du mois d’octobre 2004, les noms et prénoms des clients et des vendeurs"
    Cette fois, nous devons joindre la table commande aux deux tables client et vendeur. Là encore, une jointure interne est suffisante. Pas besoin de regroupement puisque on veut toutes les commandes d'octobre 2004. Cette requête est plus simple que la précédente :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT co.nocde, co.datecde, 
      cl.nocli, cl.nomcli, cl.pnomcli,
      v.novdeur, v.nomvdeur, v.pnomvdeur
    FROM commande AS co
    INNER JOIN clientele AS cl ON cl.nocli = co.nocli
    INNER JOIN vendeur AS v ON v.novdeur = co.novdeur
    WHERE EXTRACT(YEAR FROM co.datecde) = 2004
      AND EXTRACT(MONTH FROM co.datecde) = 10
    À part la syntaxe de la jointure, ta seconde requête dans ton premier message me semblait bonne.

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 56
    Points : 36
    Points
    36
    Par défaut
    Un très grand merci pour ces réponses claires et concises !

    --> Ma deuxième requête fonctionne parfaitement (au fait, très astucieu de "renommer" les tables !)

    --> Par contre la première requete ne fonctionne pas (je vais préciser après )

    voilà, vous me proposez :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT v.novdeur, v.nomvdeur, v.pnomvdeur, COUNT(co.nocde) AS Nombre_commandes
    FROM vendeur AS v INNER JOIN commande AS co ON co.novdeur = v.novdeur
    GROUP BY v.novdeur, v.nomvdeur
    HAVING COUNT(co.nocde) > 2
    ORDER BY COUNT(co.nocde);
    Nb : j'ai retiré les EXTRACT de la requête que vous m'avez indiqué car la question exacte est : "Afficher les vendeurs ayant réalisé plus de 2 ventes, par ordre de nombre de vente croissant" et ce quelle que soit la date de la commande.

    Cela ne fonctionne pas du tout (rien ne s'affiche alors que je devrai voir apparaitre un vendeur), le logiciel m'indiquant : "You have an error in your SQL syntax; check the manual that corresponds to MySQL server version for the right syntax to use near 'HAVING COUNT(co.nocde)>2' at line 1

    Dernière question : pourquoi le "desc" n'est pas à mettre après Order By ?? Est-ce parce que à défaut de précision "ORDER BY" classe automatiquement par ordre croissant ?

    Merci d'avance, c'est très difficile au début (en tout cas ça l'est pour moi!) j'espère être à l'aise très vite !

  7. #7
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    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 801
    Points : 34 063
    Points
    34 063
    Billets dans le blog
    14
    Par défaut
    Citation Envoyé par fanico11 Voir le message
    Nb : j'ai retiré les EXTRACT de la requête que vous m'avez indiqué car la question exacte est : "Afficher les vendeurs ayant réalisé plus de 2 ventes, par ordre de nombre de vente croissant" et ce quelle que soit la date de la commande.
    Exact !

    Cela ne fonctionne pas du tout (rien ne s'affiche alors que je devrai voir apparaitre un vendeur), le logiciel m'indiquant : "You have an error in your SQL syntax; check the manual that corresponds to MySQL server version for the right syntax to use near 'HAVING COUNT(co.nocde)>2' at line 1
    Le message d'erreur signifie qu'il trouve une erreur de syntaxe "près de", c'est à dire en général "juste avant" HAVING COUNT...

    En dehors du fait que j'ai omis dans le GROUP BY la troisième colonne du SELECT ne faisant pas l'objet d'une fonction de regroupement, mais ça ne devrait pas gêner MySQL, je ne vois aucune erreur de syntaxe dans la requête !

    Tu peux poster la structure de tes tables (résultat avec texte complet de SHOW CREATE TABLE nom_de_la_table) ainsi que la requête exacte que tu soumets au serveur ?

    Dernière question : pourquoi le "desc" n'est pas à mettre après Order By ?? Est-ce parce que à défaut de précision "ORDER BY" classe automatiquement par ordre croissant ?
    DESC, c'est justement pour préciser "en ordre décroissant" et on te le demande en ordre croissant, qui est l'ordre par défaut de MySQL, et peut-être de SQL tout court !

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 56
    Points : 36
    Points
    36
    Par défaut RECTIFICATION : PROBLEMES RESOLUS
    Finalement excusez-moi, erreur d'inatention, tout fonctionne parfaitement avec votre synthaxe !

    Donc pour conclure (si ça peut en aider d'autres) :

    --> Requete 1 : Afficher les vendeurs ayant réalisé plus de 2 ventes, par ordre de nombre de vente croissant

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT COUNT(co.nocde) AS Nombre_commandes, v.novdeur, v.nomvdeur, v.pnomvdeur 
    FROM vendeur AS v 
                INNER JOIN commande AS co ON co.novdeur = v.novdeur 
    GROUP BY v.novdeur, v.nomvdeur 
    HAVING COUNT(co.nocde) > 2 
    ORDER BY COUNT(co.nocde);
    --> Requête 2 : "Afficher pour chaque commande du mois d’octobre 2004, les noms et prénoms des clients et des vendeurs."

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT co.nocde, co.datecde, cl.nocli, cl.nomcli, cl.pnomcli, v.novdeur, v.nomvdeur, v.pnomvdeur 
    FROM commande AS co 
                INNER JOIN clientele AS cl ON cl.nocli = co.nocli 
                INNER JOIN vendeur AS v ON v.novdeur = co.novdeur 
    WHERE EXTRACT(YEAR FROM co.datecde) = 2009 
         AND EXTRACT(MONTH FROM co.datecde) = 11;
    Voilà, merci encore !

    fanico11

    PS : je n'ai par contre pas compris exactement pourquoi on n'utilise pas "DESC" à la fin de la clause ORDER by...

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 56
    Points : 36
    Points
    36
    Par défaut
    Citation Envoyé par CinePhil Voir le message
    DESC, c'est justement pour préciser "en ordre décroissant" et on te le demande en ordre croissant, qui est l'ordre par défaut de MySQL, et peut-être de SQL tout court !
    d'accord, mais alors quelle est l'utilité de ASC ??

  10. #10
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    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 801
    Points : 34 063
    Points
    34 063
    Billets dans le blog
    14
    Par défaut
    Pour être plus rigoureux, comme je l'ai dit dans mon précédent message, et même si MySQL accepte la syntaxe, même si dans ce cas précis ce n'est pas faire une entorse à la norme car il y a dépendance directe entre novdeur et les autres colonnes de la table, toutes les colonnes du SELECT ne faisant pas l'objet d'une fonction de regroupement doivent figurer dans le GROUP BY :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT COUNT(co.nocde) AS Nombre_commandes, v.novdeur, v.nomvdeur, v.pnomvdeur 
    FROM vendeur AS v 
    INNER JOIN commande AS co ON co.novdeur = v.novdeur 
    GROUP BY v.novdeur, v.nomvdeur, v.pnomvdeur 
    HAVING COUNT(co.nocde) > 2 
    ORDER BY COUNT(co.nocde);
    Dans la requête 2, tu as porté la condition sur novembre 2009 au lieu d'octobre 2004.

    PS : je n'ai par contre pas compris exactement pourquoi on n'utilise pas "DESC" à la fin de la clause ORDER by...
    "Afficher les vendeurs ayant réalisé plus de 2 ventes, par ordre de nombre de vente croissant"
    DESC, c'est pour classer par ordre décroissant !
    Si tu y tiens absolument, tu peux mettre ASC pour ascendant, c'est à dire en ordre croissant mais c'est inutile parce que c'est l'ordre par défaut.

    Voir SQLPro :
    ASC spécifie l’ordre ascendant et DESC l’ordre descendant du tri. ASC ou DESC peut être omis, dans ce cas c'est l'ordre ascendant qui est utilisé par défaut.

  11. #11
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 56
    Points : 36
    Points
    36
    Par défaut Merci ! RESOLU !
    J'ai rajouté v.pnomvdeur dans le GROUP BY (une erreur de ma part même si etc.. mieux vaut prendre de bonnes habitudes dès le départ !)

    J'ai mis novembre 2009 pour vérifier l'exécution de la requête (je n'ai aucune commande en octobre 2004 dans ma base...)

    Et pour le DESC/ASC j'ai enfin compris : l'ordre par défaut dans MySQL (et peut être tous les SQL) étant l'ordre croissant, ASC est inutile ; par contre pour ranger en ordre décroissant il faut indiquer DESC.

    Merci beaucoup !

    @ bientôt !

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

Discussions similaires

  1. [MySQL] classement en fonction du nombre de visites
    Par seriesaddict dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 07/06/2008, 15h25
  2. Réponses: 11
    Dernier message: 27/06/2006, 20h21
  3. Réponses: 8
    Dernier message: 08/06/2006, 17h05
  4. Réponses: 9
    Dernier message: 30/03/2006, 16h44
  5. Réponses: 4
    Dernier message: 31/10/2005, 17h48

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