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 et SQL. Discussion :

TOP , ORDER BY et COUNT


Sujet :

Requêtes et SQL.

  1. #1
    Inactif  

    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    3 064
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2011
    Messages : 3 064
    Points : 4 604
    Points
    4 604
    Par défaut TOP , ORDER BY et COUNT
    Bonsoir

    Je dispose deux table (anciens et lycees).

    Je souhaite compter le nombre d'anciens par lycée en affichant seulement le "top 20 " des 20 comptages d'anciens par lycée les plus importants.

    Voici la requête que j’exécute ;

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT TOP 20 LYCEES.lib_etb AS lycee, Count(*) AS nombre_etudiants_par_lycee
    FROM ANCIENS, LYCEES
    WHERE LYCEES.cod_etb=ANCIENS.cod_etb
    GROUP BY LYCEES.lib_etb, LYCEES.cod_etb
    HAVING Count(ANCIENS.cod_etb)
    ORDER BY Count(ANCIENS.cod_etb)DESC;

    Le "count" n'est pas pris en compte et la requête me renvoi les 20 premiers lycées mais par ordre alphabétique et non classé par ordre de comptage comme voulu .

    Comment remédier à la chose ?

    Merci

  2. #2
    Expert éminent
    Avatar de jimbolion
    Homme Profil pro
    Moulticien
    Inscrit en
    Janvier 2013
    Messages
    3 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Moulticien
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2013
    Messages : 3 150
    Points : 7 001
    Points
    7 001
    Billets dans le blog
    2
    Par défaut Top
    tanaka59 bonjour,

    As tu essayé de mettre le count en premier critère ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT TOP 20 Count(*) AS nombre_etudiants_par_lycee,LYCEES.lib_etb AS lycee
    FROM ANCIENS, LYCEES
    WHERE LYCEES.cod_etb=ANCIENS.cod_etb
    GROUP BY LYCEES.lib_etb, LYCEES.cod_etb
    HAVING Count(ANCIENS.cod_etb)
    ORDER BY Count(ANCIENS.cod_etb)DESC;
    Bonne journée

    JimboLion

  3. #3
    Membre expérimenté
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2010
    Messages
    793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Mayenne (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2010
    Messages : 793
    Points : 1 327
    Points
    1 327
    Par défaut
    Bonjour,

    1) C'est quoi ce "having" ? oO
    2) Intérêt de grouper par libellé et code si on affiche seulement le libellé ?
    Exemple :
    Libellé Lycée | Nombre
    Lycée Maurice Lapin | 22
    Lycée Maurice Lapin | 54
    Ce genre de résultat est assez troublant, donc affichez aussi le code, ou faites en sorte que le libelle soit unique, et dans ce cas pas besoin de grouper par code.

  4. #4
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 722
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 722
    Points : 57 381
    Points
    57 381
    Billets dans le blog
    42
    Par défaut
    bonsoir,

    avec les assistants ça se fait très bien sans connaissance du SQL et on obtient rapidement quelque chose comme:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT TOP 20 LYCEES.cod_etb, LYCEES.lib_etb AS lycee, Count(*) AS nombre_etudiants_par_lycee
    FROM ANCIENS INNER JOIN LYCEES
    ON LYCEES.cod_etb=ANCIENS.cod_etb
    GROUP BY LYCEES.lib_etb, LYCEES.cod_etb
    ORDER BY Count(*) DESC;

    privé des assistants Requête ?

    Et puis je ne serai pas surpris d'apprendre qu'il y a plusieurs lycée Maurice Papin en France.

  5. #5
    Inactif  

    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    3 064
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2011
    Messages : 3 064
    Points : 4 604
    Points
    4 604
    Par défaut
    Hello

    Alors pour être honnête je ne sais pas me servir de l’assistant réquête ,

    Après analyse de vos code voici ma solution :

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT TOP 20 Count(*) AS nombre_etudiants_par_lycee, LYCEES.lib_etb AS lycee
    FROM ANCIENS, LYCEES
    WHERE (((LYCEES.cod_etb)=[ANCIENS].[cod_etb]))
    GROUP BY LYCEES.lib_etb
    ORDER BY 1 DESC;

    Pour le "Having" on m'a toujours appris que lorsque l'on fait un comptage , une somme ou un AVG on doit toujours mettre les clauses group by et having , sinon la requete n'est pas considérer comme bonne .

    info ou intox ?

    Merci des tuyaux

  6. #6
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 722
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 722
    Points : 57 381
    Points
    57 381
    Billets dans le blog
    42
    Par défaut
    bonjour,

    Alors pour être honnête je ne sais pas me servir de l’assistant réquête ,
    c'est dommage de ne pas avoir commencé par là quand on dispose d'Access, c'est formateur pour apprendre le SQL.

    une somme ou un AVG on doit toujours mettre les clauses group by et having
    having est facultatif, on l'utilise pour filtrer une expression agrégée. Voir ici.

  7. #7
    Membre expérimenté
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2010
    Messages
    793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Mayenne (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2010
    Messages : 793
    Points : 1 327
    Points
    1 327
    Par défaut
    Le "group by" est nécessaire si on utilise une fonction d'agregat (Count, Sum, ...) avec un champ non agrégé, par exemple :

    Pas de "Group by"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Select count(B)
    FROM Table
    "Group by" sinon requête fausse puisqu'on souhaite regrouper selon le champs A
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Select A, count(B)
    FROM Table
    GROUP BY A
    "Group By" + "Having" puisque notre critère porte sur un champ agrégé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Select A, count(B)
    FROM Table
    GROUP BY A
    HAVING count(B) > 2
    "Group By", pas de "Having" puisque notre critère ne porte pas sur un champ agrégé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Select A, count(B)
    FROM Table
    GROUP BY A
    WHERE A LIKE ('Poney%')
    Sinon, selon moi, l'assistant de requête c'est pas super, la preuve avec cette ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    WHERE (((LYCEES.cod_etb)=[ANCIENS].[cod_etb]))
    ça n'est pas plus simple comme ça ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    WHERE LYCEES.cod_etb = ANCIENS.cod_etb

  8. #8
    Expert confirmé Avatar de Richard_35
    Homme Profil pro
    Inscrit en
    Juillet 2007
    Messages
    3 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 3 121
    Points : 4 596
    Points
    4 596
    Par défaut
    Bonjour à tous,

    Puisque nous sommes dans l'optique "formation", n'oublions pas le post de F-leb dont la partie
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ...
    FROM ANCIENS INNER JOIN LYCEES
    ...
    semble être passée inaperçue... bien que fondamentale !

    En effet, il faut passer par des JOIN plutôt que par des WHERE pour lier deux tables entre elles.

  9. #9
    Inactif  

    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    3 064
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2011
    Messages : 3 064
    Points : 4 604
    Points
    4 604
    Par défaut
    Citation Envoyé par Richard_35 Voir le message
    Bonjour à tous,

    Puisque nous sommes dans l'optique "formation", n'oublions pas le post de F-leb dont la partie
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ...
    FROM ANCIENS INNER JOIN LYCEES
    ...
    semble être passée inaperçue... bien que fondamentale !

    En effet, il faut passer par des JOIN plutôt que par des WHERE pour lier deux tables entre elles.
    Le INNER JOIN a des limites aussi , quand on à 3 voir plus de tables. Il faut faire un fastidieux travail de Right join / left join qui n'est pas super niveau code . Le passage par le where est bien plus simple car on fait un "saute mouton".

    Le INNER JOIN suppose aussi un différence entre tous les termes d'une table. Par exemple calculer toutes les différence entre deux dates sur une table commandes pour chaque client . En sortie Inner join nous sort tous les intervalles de dates possibles entres 2 dates de commandes pour 1 client données.

    exemple assez fastidieux avec du inner join :

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT VISITE.idanimal, MAX(VISITE.datevisite) AS dernière_visite, MAX(VISITE_1.datevisite) AS précédente_visite, DATEDIFF('d',[dernière_visite],[précédente_visite]) AS intervalle_en_jour
    FROM VISITE INNER JOIN VISITE AS VISITE_1 ON VISITE.idanimal = VISITE_1.idanimal
    WHERE (((VISITE_1.datevisite)>[VISITE].[datevisite]))
    GROUP BY VISITE.idanimal;

  10. #10
    Membre expérimenté
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2010
    Messages
    793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Mayenne (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2010
    Messages : 793
    Points : 1 327
    Points
    1 327
    Par défaut
    Je vois pas en quoi la nouvelle syntaxe est un soucis, malgré votre exemple ...

  11. #11
    Expert confirmé Avatar de Richard_35
    Homme Profil pro
    Inscrit en
    Juillet 2007
    Messages
    3 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 3 121
    Points : 4 596
    Points
    4 596
    Par défaut
    Bonjour Tanaka59,

    Si l'on veut utiliser la syntaxe Excel, le WHERE sert à établir un filtre.

    Le JOIN sert à utiliser les fonctionnalités de base des bases de données, à savoir, lier des clés étrangères à leur table respective dans lesquelles elles ne sont pas, forcément, les clés primaires mais, au minimum de préférence, un index (afin de bénéficier des performances inhérentes aux susnommées base de données).

    Citation Envoyé par Tanaka59
    exemple assez fastidieux avec du inner join :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT VISITE.idanimal, MAX(VISITE.datevisite) AS dernière_visite, MAX(VISITE_1.datevisite) AS précédente_visite, DATEDIFF('d',[dernière_visite],[précédente_visite]) AS intervalle_en_jour
    FROM VISITE INNER JOIN VISITE AS VISITE_1 ON VISITE.idanimal = VISITE_1.idanimal
    WHERE (((VISITE_1.datevisite)>[VISITE].[datevisite]))
    GROUP BY VISITE.idanimal;
    ==> via l'assistant, cette requête est limpide de simplicité. Rien ne t'empêche, après sa mise au point via l'assistant, de récupérer le code SQL pour l'intégrer dans du VBA, par exemple.

    Maintenant, effectivement, tout est possible, même d'utiliser de mauvaises méthodes (et cela, pas seulement en développement informatique).

  12. #12
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 722
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 722
    Points : 57 381
    Points
    57 381
    Billets dans le blog
    42
    Par défaut
    Citation Envoyé par tanaka59 Voir le message
    Le INNER JOIN a des limites aussi , quand on à 3 voir plus de tables. Il faut faire un fastidieux travail de Right join / left join qui n'est pas super niveau code . Le passage par le where est bien plus simple car on fait un "saute mouton".

    Le INNER JOIN suppose aussi un différence entre tous les termes d'une table. Par exemple calculer toutes les différence entre deux dates sur une table commandes pour chaque client . En sortie Inner join nous sort tous les intervalles de dates possibles entres 2 dates de commandes pour 1 client données.
    Mais qu'est ce que c'est que ces bêtises? Cela fait plus de 20 ans que la norme recommande les jointures avec JOIN.

    Jusqu'à la requête "fastidieuse" dont le code est généré en quelques clics dans l'assistant Requête

Discussions similaires

  1. ORDER BY et COUNT
    Par Zartan dans le forum Requêtes
    Réponses: 2
    Dernier message: 30/10/2007, 22h17
  2. ORDER BY RAND() sur un COUNT
    Par didier17062006 dans le forum Langage SQL
    Réponses: 2
    Dernier message: 10/02/2007, 10h14
  3. Problème ORDER BY COUNT()
    Par Gwipi dans le forum Requêtes
    Réponses: 4
    Dernier message: 19/04/2006, 16h01
  4. [SQL] Jointure,Group BY et ORDER BY COUNT qui marche pas
    Par Stef784ever dans le forum Langage SQL
    Réponses: 8
    Dernier message: 17/08/2005, 12h28
  5. faire un ORDER BY sur COUNT(*)
    Par adilou1981 dans le forum Requêtes
    Réponses: 2
    Dernier message: 20/05/2005, 11h46

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