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 count mais sans grouper.


Sujet :

Requêtes MySQL

  1. #1
    Membre habitué
    Inscrit en
    Juin 2007
    Messages
    259
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 259
    Points : 177
    Points
    177
    Par défaut Requete avec count mais sans grouper.
    Bonjour,

    Voilà, j'ai une table qui liste pour un objet donné, les id des éléments dont est constitué cet objet.
    par exemple :
    objet élément
    toto 5
    toto 8
    toto 12
    titi 4
    titi 8
    tutu 7
    tata 1
    tata 3
    tata 12
    tata 2
    signifie que l'objet toto est constitué des éléments 5 8 et12
    signifie que l'objet titi est constitué des éléments 4 et 8
    signifie que l'objet tutu est constitué de l'élément 7
    signifie que l'objet tata est constitue des éléments 1 2 3 et 12
    je cherchais une requête qui sort chaque objet s'il contient plus d'un élément et trie par le nombre d'éléments dont il constitué mais en gardant chaque ligne visible !
    tutu est constitué de 1 élément
    titi est constitué de 2 éléments
    toto est constitué de 3 éléments
    tata est constitué de 4 éléments
    et avoir une sortie du genre
    objet élément count
    titi 4 2
    titi 8 2
    toto 5 3
    toto 8 3
    toto 12 3
    tata 1 4
    tata 3 4
    tata 2 4
    tata 12 4
    si je fais un:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    select objet, count(objet) ct 
    from table 
    group by objet 
    having ct > 1 
    order by ct asc, objet asc  ;
    j'obtiens :
    titi 2
    toto 3
    tata 4
    ok, tutu n'apparait plus, mais j'ai perdu l'info de savoir quels sont les éléments dont sont constitués chaque objet.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    select objet, element, count(objet) ct 
    from table 
    group by objet 
    having ct > 1 
    order by ct asc, objet asc  ;
    j'obtiens :
    objet élément count
    titi 4 2
    toto 5 3
    tata 1 4
    Je n'ai QUE le premier élément pour chaque objet et pas les autres.
    J'ai essayé des solutions avec "distinct objet" sans succès.
    J'ai essayé d'enlever le group by car c'est lui je pense qui réalise l'agrégation des lignes, mais cela ne donne rien non plus.
    Merci pour votre aide.

  2. #2
    Membre expert
    Avatar de Maljuna Kris
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2005
    Messages
    2 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Points : 3 950
    Points
    3 950
    Par défaut
    Saluton,
    Tu devrais regarder du côté de la fonction GROUP_CONCAT.

  3. #3
    Membre habitué
    Inscrit en
    Juin 2007
    Messages
    259
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 259
    Points : 177
    Points
    177
    Par défaut
    J'ai été voir la doc mysql, j'ai rien compris sur ce que fait cette fonction !

  4. #4
    Membre expert
    Avatar de Maljuna Kris
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2005
    Messages
    2 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Points : 3 950
    Points
    3 950
    Par défaut
    Citation Envoyé par fabrice91 Voir le message
    J'ai été voir la doc mysql, j'ai rien compris sur ce que fait cette fonction !
    Dans ton cas
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    select objet, count(objet) ct, GROUP_CONCAT(`élément`) elements
    from `table` 
    group by objet
    order by ct asc, objet asc ;
    devrait te retourner une ligne par objet avec, en troisième colonne elements, la liste des éléments de l'objet séparés par des virgules.

  5. #5
    Membre habitué
    Inscrit en
    Juin 2007
    Messages
    259
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 259
    Points : 177
    Points
    177
    Par défaut
    Merci, ça marche parfaitement bien sauf que je ne comprends pas comment ça marche et ce que l'on peut mettre d'autre dans la fonction GROUP_CONCAT !
    Par exemple la liste d'éléments qui est concaténée est une liste d'id et j'aimerais dans la même requête au lieu d'afficher les id, afficher les noms des éléments, donc pour cela il faut inserer un SELECT dans la fonction GROUP_CONCAT ?

    edit: oups ça a l'air bon, j'ai mis un where derrière le from, c'est bon...

  6. #6
    Membre expert
    Avatar de Maljuna Kris
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2005
    Messages
    2 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Points : 3 950
    Points
    3 950
    Par défaut
    Citation Envoyé par fabrice91 Voir le message
    Par exemple la liste d'éléments qui est concaténée est une liste d'id et j'aimerais dans la même requête au lieu d'afficher les id, afficher les noms des éléments, donc pour cela il faut inserer un SELECT dans la fonction GROUP_CONCAT ?
    Non, il faut mettre la table en jointure avec celle qui contient les libellés des éléments et remplacer le nom de la colonne dans la fonction GROUP_CONCAT, laquelle, je le précise au passage, accepte sa propre clause ORDER BY.

  7. #7
    Membre habitué
    Inscrit en
    Juin 2007
    Messages
    259
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 259
    Points : 177
    Points
    177
    Par défaut
    oups en fait c'est partiellement résolu, mais c'est vrai que dans ma demande initiale je n'avais pas prévu d'aller si loin, récupérer les id des éléments me suffisait.
    Maintenant je dois trouver leur nom qui se trouve dans la même table puisque l'id de l'élément que je sors est lui-même un objet de la table !
    Je crois que je vais traiter ça côté applicatif et lancer une autre requête pour trouver le nom...

  8. #8
    Membre expert
    Avatar de Maljuna Kris
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2005
    Messages
    2 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Points : 3 950
    Points
    3 950
    Par défaut
    Citation Envoyé par fabrice91 Voir le message
    Maintenant je dois trouver leur nom qui se trouve dans la même table puisque l'id de l'élément que je sors est lui-même un objet de la table !
    J'ai peur de découvrir que ta table souffrirait d'un énorme défaut de conception.

  9. #9
    Membre habitué
    Inscrit en
    Juin 2007
    Messages
    259
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 259
    Points : 177
    Points
    177
    Par défaut
    Citation Envoyé par Maljuna Kris Voir le message
    J'ai peur de découvrir que ta table souffrirait d'un énorme défaut de conception.
    Arf peut être...
    Par analogie ma table est ainsi :
    j'ai des objets :
    voiture, vélo, moteur, roue, portière, capot, pédale
    chacun possède un id, son nom et l'id de l'élément qui le constitue (lui même si c'est un élément simple).
    Ex :
    id nom élément
    1 roue 1
    2 portière 2
    3 capot 3
    4 moteur 4
    5 pédale 5
    6 voiture 1
    7 voiture 2
    8 voiture 3
    9 voiture 4
    10 vélo 1
    11 vélo 5

    Une voiture est constituée des éléments 1 2 3 4 5 soit roue+portière+capot+moteur
    Un vélo est constitué des éléments 1 5 soit roue+pédale
    etc...
    Tout est objet : un objet peut être constitué soit de lui-même si c'est un objet disons "élémentaire", soit d'objets élémentaires si c'est un objet composé...
    Je ne sais pas si c'est un problème de conception mais j'avais trouvé ce moyen pour n'avoir qu'une seule table, et cela ne me semble pas illogique, sachant que je veux pouvoir parfois traiter une roue comme une voiture, c'est a dire me moquer de savoir si c'est un objet simple ou composé.
    Maintenant, c'est clair que je ne suis pas un spécialiste des BDD...

    (je rappelle que mon exemple est une analogie hein...)

  10. #10
    Membre expert
    Avatar de Maljuna Kris
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2005
    Messages
    2 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Points : 3 950
    Points
    3 950
    Par défaut
    Ah, tu me rassure, il te faut juste faire une auto-jointure, c'est à dire une jointure de la table sur elle-même, je n'ai plus le temps, là tout de suite, mais si qqun ne s'y colle pas je te montrerais ça tout à l'heure.
    En attendant, as-tu lu cet article http://sqlpro.developpez.com/cours/arborescence/ ?

  11. #11
    Membre habitué
    Inscrit en
    Juin 2007
    Messages
    259
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 259
    Points : 177
    Points
    177
    Par défaut
    Ouf tu me rassures aussi...
    Encore merci pour le temps et les références, je regarderais ça demain.

  12. #12
    Membre expert
    Avatar de Maljuna Kris
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2005
    Messages
    2 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Points : 3 950
    Points
    3 950
    Par défaut
    Quoique, quoique
    Citation Envoyé par fabrice91 Voir le message
    j'ai des objets :
    voiture, vélo, moteur, roue, portière, capot, pédale
    chacun possède un id, son nom et l'id de l'élément qui le constitue (lui même si c'est un élément simple).
    Je m'inscris en faux, l'élément voiture, par exemple n'a pas un identifiant ,mais plusieurs
    Citation Envoyé par fabrice91 Voir le message
    Ex :
    id nom élément
    1 roue 1
    2 portière 2
    3 capot 3
    4 moteur 4
    5 pédale 5
    6 voiture 1
    7 voiture 2
    8 voiture 3
    9 voiture 4

    10 vélo 1
    11 vélo 5
    Même chose pour vélo.
    Je suis donc au regret de te dire que ta table n'est pas conforme du tout aux formes normales, et son architecture ne relève pas non plus d'une relation hiérarchique simple une roue, par exemple, pouvant être rattachée à deux éléments mères voiture et vélo.
    Le éléments sont donc, potentiellement en relation plusieurs à plusieurs et tu devrais avoir une table parties dans laquelle on trouverait, pour chaque liaison élément-élément, la paire de clefs.

  13. #13
    Membre habitué
    Inscrit en
    Juin 2007
    Messages
    259
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 259
    Points : 177
    Points
    177
    Par défaut
    oui, merci, je vois ce que tu veux dire...
    La solution serait d'avoir 2 tables :

    Une table "objet" :

    id nom
    1 roue
    2 portiere
    3 capot
    4 moteur
    5 pedale
    6 voiture
    7 velo

    Et une table "liaison"

    id objet1_id objet2_id
    1 6 1
    2 6 2
    3 6 3
    4 6 4
    5 7 1
    6 7 5

    j'avais bien pensé à cette solution mais le souci c'est que dans ce cas là comment je récupère facilement l'info des objets qui sont des entités élémentaires d'après ma définition, donc roue, portiere, capot, moteur et pedale ?
    Je n'ai l'info nulle part...
    Alors soit j'ajoute un champ booléen dans la table objet pour signifier le statut de l'objet :
    0 = elementaire
    1 = composé
    ce qui donne la table "objet" :
    id nom statut
    1 roue 1
    2 portiere 1
    3 capot 1
    4 moteur 1
    5 pedale 1
    6 voiture 0
    7 velo 0

    ou bien ajouter une entrée dans la table "liaison" avec chaque élément simple pointant sur lui-même : (suite de la table "liaison" de ci-dessus)
    id objet1_id objet2_id
    7 1 1
    8 2 2
    9 3 3
    10 4 4
    11 5 5

    Bon ok, on est plus dans la catégorie "requete", plutot "conception"

  14. #14
    Membre expert
    Avatar de Maljuna Kris
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2005
    Messages
    2 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Points : 3 950
    Points
    3 950
    Par défaut
    Citation Envoyé par fabrice91 Voir le message
    mais le souci c'est que dans ce cas là comment je récupère facilement l'info des objets qui sont des entités élémentaires d'après ma définition, donc roue, portiere, capot, moteur et pedale ?
    Je n'ai l'info nulle part...
    Ça c'est déjà une info.
    Tu fais un LEFT JOIN entre la table élément et la table liaison en ne gardant que les lignes pour lesquelles objet2_id IS NULL .

  15. #15
    Membre habitué
    Inscrit en
    Juin 2007
    Messages
    259
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 259
    Points : 177
    Points
    177
    Par défaut
    Citation Envoyé par Maljuna Kris Voir le message
    Tu fais un LEFT JOIN
    Houla, j'en suis resté à lépoque du WHERE simple, donc les LEFT JOIN, RIGHT JOIN j'ai pas intégré malgré la lecture des tutos ici...la gauche de qui par rapport à quoi ? bref, je suis mal barré...
    mais bon je vais regarder de nouveau, merci...

  16. #16
    Membre expert
    Avatar de Maljuna Kris
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2005
    Messages
    2 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Points : 3 950
    Points
    3 950
    Par défaut
    Dans le cas précis, c'est vraiment simple
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT o.id,o.nom
    FROM objet o
    LEFT JOIN liaison l ON l.objet2_id=o.id
    WHERE l.objet2_id IS NULL
    http://sqlpro.developpez.com/cours/sqlaz/jointures/

  17. #17
    Membre habitué
    Inscrit en
    Juin 2007
    Messages
    259
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 259
    Points : 177
    Points
    177
    Par défaut
    En effet cette requête fonctionne, mais je ne comprends pas pourquoi...
    Et si je ne comprends pas, je n'arriverai pas à faire les miennes propres.
    En fait ta requête sort les objets composés, en l'occurrence "voiture" et "velo". Pour avoir les objets élémentaires, j'ai modifié le IS NULL par IS NOT NULL.
    Mais bon, ça ne m'explique pas le pourquoi du comment du JOIN et pourquoi LEFT et pas RIGHT...
    Je continue le tutorial, même si lui aussi me joue des tours...

  18. #18
    Membre expert
    Avatar de Maljuna Kris
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2005
    Messages
    2 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Points : 3 950
    Points
    3 950
    Par défaut
    Pour les jointures externes, c'est là :
    http://sqlpro.developpez.com/cours/s...ntures/#LIII-C

  19. #19
    Membre habitué
    Inscrit en
    Juin 2007
    Messages
    259
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 259
    Points : 177
    Points
    177
    Par défaut
    Citation Envoyé par Maljuna Kris Voir le message
    Pour les jointures externes, c'est là :
    http://sqlpro.developpez.com/cours/s...ntures/#LIII-C
    oui je sais bien mais je n'arrive pas à reproduire le résultat comme tu peux le voir sur l'autre sujet où tu as la gentillesse de me répondre...
    Donc lire un tutorial et ne pas arriver à le reproduire, soit cela vient de moi soit cela vient du tutorial !
    Dans ta solution que tu m'as donné plus haut, j'ai remplaçé LEFT par RIGHT pour voir et je n'ai pas du tout le même résultat ! c'est certainement normal mais je ne vois pas pourquoi...
    Lorsque j'aurai compris pourquoi un LEFT plutot qu'un RIGHT ce sera gagné...

  20. #20
    Membre expert
    Avatar de Maljuna Kris
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2005
    Messages
    2 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Points : 3 950
    Points
    3 950
    Par défaut
    A la limite, peu importe, prend l'habitude de mettre en premier (donc à gauche LEFT) la table dont tu attends toutes les lignes (sauf celles filtrées par le WHERE) et après le LEFT JOIN la table 'accessoire', celle pour les colonnes de laquelle tu recevras des NULL quand la jointure ne sera pas réalisée (clause ON retournant FALSE).

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

Discussions similaires

  1. Double requete avec _GET mais pas avec _POST
    Par rickilami dans le forum Langage
    Réponses: 2
    Dernier message: 17/11/2008, 16h03
  2. [mysql 5] requete avec count+ having + group by
    Par epeichette dans le forum Requêtes
    Réponses: 7
    Dernier message: 29/10/2008, 19h52
  3. Requetes Avec Count et condition sur date
    Par Harry dans le forum WinDev
    Réponses: 1
    Dernier message: 04/06/2007, 15h23
  4. Comment optimiser une Requete avec Count ?
    Par tavarlindar dans le forum Requêtes
    Réponses: 15
    Dernier message: 09/02/2007, 21h19

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