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 :

Requête mysql : Problème de jointure et de groupement des données


Sujet :

Requêtes MySQL

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 11
    Points : 5
    Points
    5
    Par défaut Requête mysql : Problème de jointure et de groupement des données
    Bonsoir,

    je cherche depuis un moment à réaliser une requête assez complexe dont voici en gros la tête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    SELECT c.* ,
    GROUP_CONCAT(DISTINCT u.login SEPARATOR ",") AS read_by,
    GROUP_CONCAT(DISTINCT u.email SEPARATOR ",") AS em_read_by,
    GROUP_CONCAT(DISTINCT u2.login SEPARATOR ",") AS reply_by,
    GROUP_CONCAT(DISTINCT u2.email SEPARATOR ",") AS em_reply_by
    FROM contact c, user u, user u2
    WHERE c.id_contact=1
    AND c.read_by IN (SELECT id_user FROM user)
    AND c.answered_by IN (SELECT id_user FROM user)
    GROUP BY c.id_contact

    Bon, évidement la requête est vraiment moche et mal foutu, mais peut-être y voyez vous plus clair dans mes intentions.
    Si ce n'est pas le cas, en fait je cherche à retourner en une requête un seul enregistrement regroupement des données de deux tables différentes.

    Quelques infos sur les champs:
    Le champ 'c.read_by' et 'c.answered_by' sont de type CHAR et contiennent une entrée de la forme : '1,3,5,' (les chiffres correspondant aux ID des membres de la table user)

    Ce qui m'est retourné lors de la requête (un seul retour/résultat j'ai bien dit) (j'ai enlevé ce qui importait peu):
    _______________________________________________________________________________________
    |c.id_contact | read_by.................| em_read_by.........| reply_by.................| em_reply_by |
    ------------------------------------------------------------------------------------------------------------------------
    |1............. | Pseudo1,Pseudo2, etc..| email@email.fr, etc..| Pseudo1,Pseudo2, etc..| email@email.fr, etc..

    Donc en gros ma requête transforme les ID du champ c.read_by par les pseudos correspondant.
    Cependant, et c'est là mon problème, je me retrouve avec le champ resultat 'read_by' contenant TOUT les ID de ma table user transformés en pseudo, alors que je ne veux récupérer que les pseudos des ID contenu dans le champ c.read_by.

    C'est un module de contact que je réalise et je veux faire en sorte que les membres puisse marquer comme lu les messages envoyés par les visiteurs, pour ainsi afficher dans mon administration qui a lu le message.

    A mon avis je me complique bien la vie, en 2 requêtes c'est torché mais je suis pourtant persuadé qu'en une seule y a moyen d'arriver à ce que je veux.

    Bref si quelqu'un a une idée :s . Le problème vient du IN à mon avis, qui n'est pas judicieux ou mal utilisé peut-être.
    Si on pouvais comparer dans une requête deux array ce serait génial mais je n'ai pas trouvé comment et je ne crois pas que mysql sache le faire..
    Si il vous manque des infos ou que ce n'est pas très clair dites le j'essairai de refaire ça mieux..

    Merci d'avance.

  2. #2
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    Bon après quelques test et recherche j'en suis arrivé à une requête plus simple mais qui me pose un autre problème:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT c.read_by, u.id_user, GROUP_CONCAT(DISTINCT u.login SEPARATOR ", ") AS read_by
    FROM contact c, user u
    WHERE c.id_contact =1
    AND u.id_user IN ( c.read_by )
    GROUP BY c.id_contact
    c.read_by est du type string qui est une suite de chiffre séparé par des virgules: "1,3,4,8,(etc...)"
    Mon problème est bien justement que ce champ est du type string !
    Car pour faire fonctionner ma requête, plus particulièrement le IN (), il faudrait que ce soit ainsi (donc sans les guillemets!) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT c.read_by, u.id_user, GROUP_CONCAT(DISTINCT u.login SEPARATOR ", ") AS read_by
    FROM contact c, user u
    WHERE c.id_contact =1
    AND u.id_user IN ( 1,3,4,8,(etc...) )
    GROUP BY c.id_contact
    Donc ma question est, comment faire pour transformer un string : "1,3,4,8" en un type non string de la forme : 1,3,4,8 (sans les guillemets particulier du string)
    Un type float ou decimal ne règle pas le problème car seulement ce qu'il y a après la première virgule est gardé...
    Si vous avez une idée... merci d'avance :/

  3. #3
    ced
    ced est déconnecté
    Rédacteur/Modérateur

    Avatar de ced
    Homme Profil pro
    Gestion de bases de données techniques
    Inscrit en
    Avril 2002
    Messages
    6 040
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Gestion de bases de données techniques
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2002
    Messages : 6 040
    Points : 23 795
    Points
    23 795
    Par défaut
    Bonjour,

    Pourquoi ne pas mettre une sous-requête dans le IN (...) qui ramènerait les différents read_by que tu souhaites ? Au moins, là, tu es sûr que ça marcherait.
    Il faut juste que ta version de MySQL soit supérieure ou égale à la 4.1.

    ced

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    J'ai déjà essayé mais ça ne fonctionne pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT c.read_by, u.id_user
    FROM contact c, user u
    WHERE c.id_contact =1
    AND u.id_user IN ( SELECT read_by FROM contact )
    GROUP BY c.id_contact
    Il m'est retourné :
    read_by : 1,3,4,
    id_user : 1

    J'aimerais :
    read_by : 1,3,4,
    id_user : 1,3,4

    (j'ai aussi essayé en enlevant la virgule à la fin du champ read_by mais rien n'y change)

    Je ne comprends pas pourquoi ça ne fonctionne pas :/
    PS: ma version de mysql est la 5

  5. #5
    ced
    ced est déconnecté
    Rédacteur/Modérateur

    Avatar de ced
    Homme Profil pro
    Gestion de bases de données techniques
    Inscrit en
    Avril 2002
    Messages
    6 040
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Gestion de bases de données techniques
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2002
    Messages : 6 040
    Points : 23 795
    Points
    23 795
    Par défaut
    Mille excuses, c'est de ma faute . J'ai mal lu ton premier post !
    Si j'ai bien tout compris, c.read_by est une chaîne concaténée des id des utilisateurs qui ont lu le post. C'est ça ?
    Dans ce cas, le IN ne peut rien, et il faut plutôt utiliser la fonction FIND_IN_SET(), qui donne la position d'une chaîne dans une liste constituée de chaînes séparées par une virgule (j'insiste sur la virgule, sinon ça ne va pas marcher).
    La requête deviendrait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT c.read_by, u.id_user
    FROM contact c, user u
    WHERE c.id_contact =1
    AND FIND_IN_SET(u.id_user, c.read_by) > 0
    GROUP BY c.id_contact
    A tester, pour voir si ça résout ton problème...

    ced

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    Tu as tout compris mais :

    D'où tu sort cette fonction ?!
    Ca fonctionne parfaitement bien, c'est ce que je voulais !
    Nan franchement je suis sur le cul, j'ai passé deux soirées entières à rechercher sur google, des forums et dans la doc mysql j'ai jamais vu cette fonction là, je commencais à me dire que mysql c'est vraiment trop nul :/
    Bon ben écoute je te remercie vraiment beaucoup !
    D'un autre côté ça m'énerve de pas connaitre ces petites fonctions cachées qui sont peu utilisés mais tellement pratique (du moins c'est mon impression et je ne dois pas chercher là où il faut mais bon...).

    Encore merci, ça me dépanne vraiment beaucoup

  7. #7
    ced
    ced est déconnecté
    Rédacteur/Modérateur

    Avatar de ced
    Homme Profil pro
    Gestion de bases de données techniques
    Inscrit en
    Avril 2002
    Messages
    6 040
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Gestion de bases de données techniques
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2002
    Messages : 6 040
    Points : 23 795
    Points
    23 795
    Par défaut
    Ben, une fois que j'ai compris le problème, je n'ai rien fait de plus que lire la doc MySQL sur les fonctions de chaînes de caractères et essayer de trouver la plus adaptée à ton cas...
    C'est effectivement plein de fonctions, parfois très subtiles, mais on trouve presque toujours son bonheur.

    Bon courage pour la suite...

    ced

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

Discussions similaires

  1. requête mysql, problème de champs
    Par thom48 dans le forum Requêtes
    Réponses: 6
    Dernier message: 23/03/2010, 17h58
  2. [MySQL] requête MySQL à problème
    Par laurentSc dans le forum PHP & Base de données
    Réponses: 18
    Dernier message: 15/12/2009, 17h13
  3. [MySQL] Requête MySQL : problèmes avec les espaces
    Par superseba888 dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 06/07/2007, 17h12
  4. [MySQL] Problème d'encodage / transfert de base de données
    Par Theberge43 dans le forum Langage SQL
    Réponses: 2
    Dernier message: 30/01/2007, 19h21
  5. [Requêtes SQL] Problème de jointure ?
    Par soso78 dans le forum Requêtes et SQL.
    Réponses: 6
    Dernier message: 18/12/2006, 16h37

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