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 :

Compter sur une table à partir d’une autre


Sujet :

Requêtes MySQL

  1. #1
    Membre averti
    Inscrit en
    Mai 2013
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Mai 2013
    Messages : 16
    Par défaut Compter sur une table à partir d’une autre
    Bonjour,

    J’ai une base avec deux tables :

    La table utilisateur avec Nom, prénom et localisation,

    La table Commune avec les noms des villes sous NCCENR.

    Je voudrais compter le nombre de fois qu’une ville est associée à un utilisateur.

    NCCENR COUNT

    Paris 12

    Nantes 33

    ...

    PS : la localisation est rentrée par l’utilisateur et peut donc contenir des caractères en plus de la ville « from Paris »…

    Voici la requête que j'ai réalisée:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT commune.NCCENR, COUNT(*)
    FROM `BASE`.`refcommune` as commune
    left join `BASE`.`utilisateur` as user on user.Localisation like commune.NCCENR
    GROUP BY NCCENR;
    Mais elle me retourne 1 pour toutes les villes

    Je travail sur MySQL Workbench 5.2.47

    Merci.

  2. #2
    Membre Expert
    Homme Profil pro
    Développeur C++
    Inscrit en
    Avril 2012
    Messages
    771
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur C++
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2012
    Messages : 771
    Par défaut
    Bonjour,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT commune.NCCENR, COUNT(user.nom)
    FROM `BASE`.`refcommune` AS commune
    LEFT JOIN `BASE`.`utilisateur` AS user ON user.Localisation LIKE commune.NCCENR
    GROUP BY NCCENR;
    Il faut préciser la table user pour le count.

  3. #3
    Membre averti
    Inscrit en
    Mai 2013
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Mai 2013
    Messages : 16
    Par défaut
    Merci pour ta réponse Exia93,
    Mais cela ne marche toujours pas, j'obtiens maintenant 0 pour chaques villes

  4. #4
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Par défaut
    Bonjour,

    Le LIKE tel que vous le faites revient à un =...

    essayez ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT commune.NCCENR, COUNT(user.nom)
    FROM `BASE`.`refcommune` AS commune
    LEFT JOIN `BASE`.`utilisateur` AS user ON user.Localisation LIKE '%' + commune.NCCENR + '%'
    GROUP BY NCCENR;

  5. #5
    Membre Expert
    Homme Profil pro
    Développeur C++
    Inscrit en
    Avril 2012
    Messages
    771
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur C++
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2012
    Messages : 771
    Par défaut
    La colonne Localisation de la table user est-elle bien une clé étrangère vers la colonne NCCENR de la table Commune ?

  6. #6
    Membre averti
    Inscrit en
    Mai 2013
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Mai 2013
    Messages : 16
    Par défaut
    Citation Envoyé par aieeeuuuuu Voir le message
    Bonjour,

    Le LIKE tel que vous le faites revient à un =...

    essayez ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT commune.NCCENR, COUNT(user.nom)
    FROM `BASE`.`refcommune` AS commune
    LEFT JOIN `BASE`.`utilisateur` AS user ON user.Localisation LIKE '%' + commune.NCCENR + '%'
    GROUP BY NCCENR;
    J'ai essayé ta méthode mais cela ne marche pas ,j'obtiens 0 pour chaques villes

  7. #7
    Membre averti
    Inscrit en
    Mai 2013
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Mai 2013
    Messages : 16
    Par défaut
    Citation Envoyé par Exia93 Voir le message
    La colonne Localisation de la table user est-elle bien une clé étrangère vers la colonne NCCENR de la table Commune ?
    Je ne peux pas déclarer Localisation comme clé étrangère de NCCENR car Localisation n'est pas une clé primaire

  8. #8
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Par défaut
    pardon, mauvaise concaténation de ma part pour MySQL:

    c'est plutot ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT commune.NCCENR, COUNT(user.nom)
    FROM `BASE`.`refcommune` AS commune
    LEFT JOIN `BASE`.`utilisateur` AS user ON user.Localisation LIKE CONCAT('%', commune.NCCENR , '%')
    GROUP BY NCCENR;

  9. #9
    Membre Expert
    Avatar de ericd69
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2011
    Messages
    1 919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2011
    Messages : 1 919
    Billets dans le blog
    1
    Par défaut
    salut

    je ne crois pas que le + concatène, il transforme plutôt le résultat en nombre...
    utilise plutôt:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    concat('%',commune.NCCENR,'%')
    dans le like

  10. #10
    Membre averti
    Inscrit en
    Mai 2013
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Mai 2013
    Messages : 16
    Par défaut
    Citation Envoyé par ericd69 Voir le message
    salut

    je ne crois pas que le + concatène, il transforme plutôt le résultat en nombre...
    utilise plutôt:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    concat('%',commune.NCCENR,'%')
    dans le like
    oui c'est ce que j'avais utilisé pour tester la méthode de aieeeuuuuu et le résultat reste le même...

  11. #11
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Par défaut
    il faudrait fournir un jeu d'essai. La requête me semble bonne !

    deux questions tout de même :

    - est-ce que les noms sont bien renseignés dans voter base ? ou est-ce qu'ils sont à NULL ?
    - quelle est la collation des colonnes user.Localisation et commune.NCCENR ?

  12. #12
    Membre averti
    Inscrit en
    Mai 2013
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Mai 2013
    Messages : 16
    Par défaut
    Oui les noms sont tous renseignés.Je ne comprends pas ce que tu entends par collation entre les colonnes.

    Je mets en PJ le code et les fichiers de jeu de données, peut etre que cela aidera.

    Merci pour votre aide.
    Fichiers attachés Fichiers attachés

  13. #13
    Membre Expert
    Homme Profil pro
    Développeur C++
    Inscrit en
    Avril 2012
    Messages
    771
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur C++
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2012
    Messages : 771
    Par défaut
    Chez moi j'obtient bien le résulat voulu seulement vue qu'il y'a 36000 communes et que 13 utilisateurs tu as beaucoup de commune avec 0 utilisateur.

    Pour voir si la jointure ce fait bien il suffit de faire la vérification en affichant seulement les commune avec plus d'1 utilisateur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    SELECT commune.NCCENR, COUNT(user.nom)
    FROM `refcommune` AS commune
    LEFT JOIN `utilisateur` AS user ON user.Localisation = commune.NCCENR
    GROUP BY NCCENR
    HAVING COUNT(user.nom) > 0
     
    -- Ou plus logiquement en utilisant une jointure interne
    SELECT commune.NCCENR, COUNT(user.nom)
    FROM `refcommune` AS commune
    INNER JOIN `utilisateur` AS user ON user.Localisation = commune.NCCENR
    GROUP BY NCCENR
    De plus j'utilise l'opérateur = au lieu de like vue que je ne fait pas de traitement sur la chaîne de caractère.

  14. #14
    Membre très actif
    Profil pro
    Administrateur
    Inscrit en
    Mai 2008
    Messages
    237
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Administrateur
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2008
    Messages : 237
    Par défaut
    J'ai appliqué ces commandes pour nettoyer les sauts de ligne sur les colonnes Localisation et NCCENR

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    update `refcommune` set `NCCENR` = replace(`NCCENR` ,'\r','');
    update `refcommune` set `NCCENR` = replace(`NCCENR` ,'\n','');
    update `refcommune` set `NCCENR` = replace(`NCCENR` ,'\r\n','');
     
    update `utilisateur` set `Localisation` = replace(`Localisation` ,'\r','');
    update `utilisateur` set `Localisation` = replace(`Localisation` ,'\n','');
    update `utilisateur` set `Localisation` = replace(`Localisation` ,'\r\n','');
    Changer le COUNT(*) en COUNT(user.nom) supprime les 1 retournés pour chaque ville.
    La requête suivante fonctionne bien (environ 3 secondes) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT c.NCCENR, COUNT(r.nom) total
    FROM refcommune c
    LEFT JOIN utilisateur r ON r.Localisation = c.NCCENR
    GROUP BY c.NCCENR
    ORDER BY total DESC
    J'ai aussi ajouté des index sur les champs NCCENR et Localisation et cela m'a permis de diviser le temps d'exécution en 10. Il sera difficile d'optimiser d'une telle requête. Les meilleures performances sont obtenues avec la requête ci-dessous (environ 0.008 secondes) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT c.NCCENR, COUNT(r.nom) total
    FROM refcommune c, utilisateur r
    WHERE r.Localisation = c.NCCENR
    GROUP BY c.NCCENR
    ORDER BY total DESC

  15. #15
    Membre Expert
    Homme Profil pro
    Développeur C++
    Inscrit en
    Avril 2012
    Messages
    771
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur C++
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2012
    Messages : 771
    Par défaut
    Les deux dernières requêtes que tu donne sont complètement différente la première est une jointure externe tandis que la dernière une interne seulement elle est écrite comme il y'a 20 ans :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    -- Ecriture actuelle et plus lisible je trouve
    SELECT c.NCCENR, COUNT(r.nom) total
    FROM refcommune c
    INNER JOIN utilisateur r ON r.Localisation = c.NCCENR
    GROUP BY c.NCCENR
    ORDER BY total DESC

  16. #16
    Membre averti
    Inscrit en
    Mai 2013
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Mai 2013
    Messages : 16
    Par défaut
    Merci pour votre aide.
    D’après ce que vous me dite le problème doit être résolu, cependant en prenant vos solutions j'obtiens des colonnes vides, le problème doit donc venir d'ailleurs.

  17. #17
    Membre Expert
    Homme Profil pro
    Développeur C++
    Inscrit en
    Avril 2012
    Messages
    771
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur C++
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2012
    Messages : 771
    Par défaut
    Si c'est lorsque vous utilisez la jointure externe c'est qu'il ne doit pas y avoir d'enregistrement dans la table utilisateur pour une commune et donc 0 est retourné.

  18. #18
    Membre averti
    Inscrit en
    Mai 2013
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Mai 2013
    Messages : 16
    Par défaut
    Citation Envoyé par Exia93 Voir le message
    Si c'est lorsque vous utilisez la jointure externe c'est qu'il ne doit pas y avoir d'enregistrement dans la table utilisateur pour une commune et donc 0 est retourné.
    non il retourne rien c'est a dire je n'ai même pas la liste des villes affichée.

  19. #19
    Membre Expert
    Homme Profil pro
    Développeur C++
    Inscrit en
    Avril 2012
    Messages
    771
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur C++
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2012
    Messages : 771
    Par défaut
    Si tu n'a aucun résultat c'est que la clause de jointure ON r.Localisation = c.NCCENR n'est pas valide, que contiennent exactement c'est deux colonnes ?

  20. #20
    Membre averti
    Inscrit en
    Mai 2013
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Mai 2013
    Messages : 16
    Par défaut
    Citation Envoyé par Exia93 Voir le message
    Si tu n'a aucun résultat c'est que la clause de jointure ON r.Localisation = c.NCCENR n'est pas valide, que contiennent exactement c'est deux colonnes ?
    Localisation contient le nom de ville renseigné par l'utilisateur et NCCENR contient la liste de toutes les villes de france. J'ai joints les fichiers dans un des messages au dessus.

Discussions similaires

  1. Réponses: 2
    Dernier message: 03/09/2009, 17h02
  2. compter sur une ligne à partir de derniere cellule non vide
    Par oscar.cesar dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 03/04/2009, 19h23
  3. Réponses: 4
    Dernier message: 03/07/2008, 16h53
  4. Réponses: 1
    Dernier message: 11/04/2008, 17h08
  5. faire une requête sur une table d'un autre schéma
    Par kineton dans le forum PostgreSQL
    Réponses: 2
    Dernier message: 10/04/2008, 16h08

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