[MYSQL] Problème de jointure
Fermé
wingover
Messages postés
21
Date d'inscription
lundi 15 décembre 2008
Statut
Membre
Dernière intervention
17 juin 2011
-
8 janv. 2009 à 18:39
toto - 12 janv. 2009 à 15:40
toto - 12 janv. 2009 à 15:40
A voir également:
- [MYSQL] Problème de jointure
- Mysql community server - Télécharger - Bases de données
- Phpmyadmin a tenté de se connecter au serveur mysql, et le serveur a rejeté la connexion. merci de vérifier les valeurs de host, username et password dans la configuration et de s'assurer qu'elles correspondent aux informations fournies par l'administrateur du serveur mysql. ✓ - Forum PHP
- Mysql error 1 ✓ - Forum Réseaux sociaux
- Mysql fatal error ✓ - Forum MySQL
- Delete avec jointure ✓ - Forum Bases de données
11 réponses
wingover
Messages postés
21
Date d'inscription
lundi 15 décembre 2008
Statut
Membre
Dernière intervention
17 juin 2011
9 janv. 2009 à 13:11
9 janv. 2009 à 13:11
Bon mon problème est peut être un peu compliqué expliqué comme ça alors je vais poser ma question autrement en gardant que le fond du problème:
Si je joins ma table "distrib" avec ma table "action" de telle sorte que repart.id_action=action.id j'aurais donc
une table du genre:
Là dessus je veux extraire les infos concernant le user d'id=4, qu'il soit dans auteur ou id_user (ceci étant
précisé par le flag "role"). Le résultat devrait ressembler à ça, les résultats étant groupés par action:
J'essayé la requête:
Ca me donne ça:
Donc comment récupérer les autres lignes lorsque l'utilisateur n'est pas auteur ?
J'avais pensé à ça:
Mais ça me donne grosso modo quelque chose comme ça (avec des permutations étranges sur id_user):
Il faudrait donc une sorte de mix entre les deux. Mais j'ai plus d'idées là...
Si je joins ma table "distrib" avec ma table "action" de telle sorte que repart.id_action=action.id j'aurais donc
une table du genre:
table: "action JOIN distrib" ------------------------------ | id_user | label | auteur | ------------------------------ | 1 | action1 | 4 | | 2 | action1 | 4 | | 3 | action1 | 4 | | 2 | action2 | 1 | | 4 | action2 | 1 | ------------------------------
Là dessus je veux extraire les infos concernant le user d'id=4, qu'il soit dans auteur ou id_user (ceci étant
précisé par le flag "role"). Le résultat devrait ressembler à ça, les résultats étant groupés par action:
------------------------------------- | id_user | label | auteur | role | ------------------------------------- | 1 | | | | | 2 | action1 | 4 | 1 | | 3 | | | | ------------------------------------- | 2 | action2 | 1 | 0 | | 4 | | | | -------------------------------------
J'essayé la requête:
SELECT a.label, IF(a.auteur=4 , 1 , 0 ) role, FROM action a JOIN distrib d ON d.id_action = a.id WHERE a.auteur=4 OR d.id_user=4 GROUP BY d.id_action
Ca me donne ça:
------------------------------------- | id_user | label | auteur | role | ------------------------------------- | 1 | | | | | 2 | action1 | 4 | 1 | | 3 | | | | ------------------------------------- | 4 | action2 | 1 | 0 | -------------------------------------
Donc comment récupérer les autres lignes lorsque l'utilisateur n'est pas auteur ?
J'avais pensé à ça:
SELECT a.label, IF(a.auteur=4 , 1 , 0 ) role, FROM action a JOIN distrib d1 ON d1.id_action = a.id JOIN distrib d2 ON d2.id_action = a.id WHERE a.auteur=4 OR d.id_user=4 GROUP BY d1.id_action
Mais ça me donne grosso modo quelque chose comme ça (avec des permutations étranges sur id_user):
------------------------------------- | id_user | label | auteur | flag | ------------------------------------- | 1 | | | | | 2 | action1 | 4 | 1 | | 3 | | | | ------------------------------------- | 1 | | | | | 2 | action1 | 4 | 1 | | 3 | | | | ------------------------------------- | 3 | | | | | 1 | action1 | 4 | 1 | | 2 | | | | ------------------------------------- | 2 | action2 | 1 | 0 | | 4 | | | | -------------------------------------
Il faudrait donc une sorte de mix entre les deux. Mais j'ai plus d'idées là...
Il y a sûrement quelque chose que je ne comprends pas dans ta demande.
Tu dis, si je comprends bien, que
Mais en quoi cette ligne concerne-t-elle l'id_user 4 ?
quelle(s) étape(s) ai-je manquée(s) ?
Tu dis, si je comprends bien, que
------------------------------------- | id_user | label | auteur | role | ------------------------------------- | 1 | | | | | 2 | action1 | 4 | 1 | | 3 | | | | ------------------------------------- | 4 | action2 | 1 | 0 | -------------------------------------est incomplet, qu(il manque la ligne
| 2 | action2 | 1 | 0 |
Mais en quoi cette ligne concerne-t-elle l'id_user 4 ?
quelle(s) étape(s) ai-je manquée(s) ?
wingover
Messages postés
21
Date d'inscription
lundi 15 décembre 2008
Statut
Membre
Dernière intervention
17 juin 2011
9 janv. 2009 à 20:29
9 janv. 2009 à 20:29
Exactement.
Dans tous les cas, que l'individu soit auteur ou destinataire de l'action (c'est à dire que son id soit dans la colonne auteur ou id_user de la table action JOIN distrib) j'aimerais toujours récupérer la totalité des destinataires de l'action. Donc c'est bien un résultat de ce type que je cherche à avoir :
Dans la seconde requête j'avais imaginé récupérer cette ligne en joignant une deuxième fois la table distrib et qui ne subirait pas le filtre précédent. Je récupère effectivement la ligne manquante mais j'ai alors plein de lignes en trop dans le cas où l'utilisateur est acteur.
N'oublions pas que le cas "l'utilisateur est à la fois acteur et récepteur" peut exister.
Dans tous les cas, que l'individu soit auteur ou destinataire de l'action (c'est à dire que son id soit dans la colonne auteur ou id_user de la table action JOIN distrib) j'aimerais toujours récupérer la totalité des destinataires de l'action. Donc c'est bien un résultat de ce type que je cherche à avoir :
------------------------------------- | id_user | label | auteur | role | ------------------------------------- | 1 | | | | | 2 | action1 | 4 | 1 | | 3 | | | | ------------------------------------- | 2 | action2 | 1 | 0 | | 4 | | | | -------------------------------------Or quand j'applique mon filtre d.id_user=4 dans la clause WHERE, la fameuse ligne disparait.
Dans la seconde requête j'avais imaginé récupérer cette ligne en joignant une deuxième fois la table distrib et qui ne subirait pas le filtre précédent. Je récupère effectivement la ligne manquante mais j'ai alors plein de lignes en trop dans le cas où l'utilisateur est acteur.
N'oublions pas que le cas "l'utilisateur est à la fois acteur et récepteur" peut exister.
wingover
Messages postés
21
Date d'inscription
lundi 15 décembre 2008
Statut
Membre
Dernière intervention
17 juin 2011
9 janv. 2009 à 20:34
9 janv. 2009 à 20:34
En fait pour résumer, le vrai énoncé serait:
Je souhaite récupérer toutes les infos (acteur,destinataires) concernant les actions dans lequelles un utilisateur donné est impliqué que ce soit en tant qu'auteur ou en tant que destinataire.
Je souhaite récupérer toutes les infos (acteur,destinataires) concernant les actions dans lequelles un utilisateur donné est impliqué que ce soit en tant qu'auteur ou en tant que destinataire.
Ceci est contradictoire avec ton premier exemple (post initial) dans lequel il n'apparaissait pas que l'action 2 avait eu 2 destinataires. Tu confirmes bien ta définition du post 4 ?
Si un utilisateur est à la fois auteur et destinataire, la ligne correspondante apparaît 2 fois : une fois avec role à 0 et une fois avec role à 1 ? Sinon, quelle valeur donner à role ?
Si un utilisateur est à la fois auteur et destinataire, la ligne correspondante apparaît 2 fois : une fois avec role à 0 et une fois avec role à 1 ? Sinon, quelle valeur donner à role ?
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
wingover
Messages postés
21
Date d'inscription
lundi 15 décembre 2008
Statut
Membre
Dernière intervention
17 juin 2011
10 janv. 2009 à 14:01
10 janv. 2009 à 14:01
Pour ce qui est de l'action2, il me semble bien que les deux destinataires apparaissent dans la table distrib de mon premier post.
Pour ce qui est du cas où l'utilisateur est à la fois auteur et destinataire, c'est vrai que ce cas est indéterminé au niveau de la sortie role. On va dire alors que dans ce cas role vaudra 2 ce qui devrait se traduire dans la requête par :
Je confirme bien l'énoncé du post 4.
Je vais d'ailleurs compléter les tables action et distrib pour faire apparaître le dernier cas ainsi qu'un cas où l'utilisateur 4 n'est ni auteur ni destinataire.
Les tables à utiliser sont donc:
Le résultat pour l'utilisateur 4 devra donc être:
Pour ce qui est du cas où l'utilisateur est à la fois auteur et destinataire, c'est vrai que ce cas est indéterminé au niveau de la sortie role. On va dire alors que dans ce cas role vaudra 2 ce qui devrait se traduire dans la requête par :
IF(a.auteur=4 ,IF(d.id_user=4 , 2 , 1 ) , 0 ) role,
Je confirme bien l'énoncé du post 4.
Je vais d'ailleurs compléter les tables action et distrib pour faire apparaître le dernier cas ainsi qu'un cas où l'utilisateur 4 n'est ni auteur ni destinataire.
Les tables à utiliser sont donc:
table: action ------------------------- | id | label | auteur | ------------------------- | 1 | action1 | 4 | | 2 | action2 | 1 | | 3 | action3 | 4 | | 4 | action4 | 3 | ------------------------- table : distrib ----------------------- | id_action | id_user | ----------------------- | 1 | 1 | | 1 | 2 | | 1 | 3 | | 2 | 2 | | 2 | 4 | | 3 | 1 | | 3 | 3 | | 3 | 4 | | 4 | 1 | | 4 | 2 | -----------------------
Le résultat pour l'utilisateur 4 devra donc être:
------------------------------------- | id_user | label | auteur | role | ------------------------------------- | 1 | | | | | 2 | action1 | 4 | 1 | | 3 | | | | ------------------------------------- | 2 | action2 | 1 | 0 | | 4 | | | | ------------------------------------- | 1 | | | | | 3 | action3 | 4 | 2 | | 4 | | | | -------------------------------------
wingover
Messages postés
21
Date d'inscription
lundi 15 décembre 2008
Statut
Membre
Dernière intervention
17 juin 2011
10 janv. 2009 à 14:25
10 janv. 2009 à 14:25
Ok, j'ai compris à quel niveau c'était contradictoire avec le premier post. Tu parlais surement de ce résultat où n'apparaissaient pas les destinataires de l'action 2.
C'est vrai que je n'affiche pas les autres destinataires lorsque l'utilisateur est recepteur, mais j'en aurai quand même besoin pour d'autres opérations que je ferai en php. Bref pour que l'exemple du premier post soit cohérent avec le reste le résultat souhaité serait plutôt :
------------------------------------------------------- | label | role | commentaires | ------------------------------------------------------- | action1 | auteur | destinataires: pim,pam,poum | | action2 | recepteur | auteur: pim | -------------------------------------------------------
C'est vrai que je n'affiche pas les autres destinataires lorsque l'utilisateur est recepteur, mais j'en aurai quand même besoin pour d'autres opérations que je ferai en php. Bref pour que l'exemple du premier post soit cohérent avec le reste le résultat souhaité serait plutôt :
------------------------------------------------ | label | role | auteur | destinataires | ------------------------------------------------ | action1 | auteur | toto | pim,pam,poum | | action2 | recepteur | pim | pam,toto | ------------------------------------------------
Je me suis pas expert en mysql, et mes quelques tentatives sont infructueuses.
Tu tiens à l'avoir en une seule requête pour l'amour de l'art, ou il y a un raison plus profonde ?
Tu tiens à l'avoir en une seule requête pour l'amour de l'art, ou il y a un raison plus profonde ?
wingover
Messages postés
21
Date d'inscription
lundi 15 décembre 2008
Statut
Membre
Dernière intervention
17 juin 2011
10 janv. 2009 à 21:42
10 janv. 2009 à 21:42
Pas spécialement mais je cherche à optimiser le truc. Mais c'est vrai qu'en faisant deux requêtes, une première pour récupérer la liste des actions et une seconde pour récupérer les destinataires associés à actions, ça ne devrait pas être trop lourd.
Sauf si quelqu'un a une meilleure idée.
Sauf si quelqu'un a une meilleure idée.
Je ne suis pas sûr que faire une seule requête complètement tordue soit optimal par rapport à deux requêtes plus 'ordinaires'.
Mais tu as raison, peut-être qu'un gourou de passage pourra te donner satisfaction.
Mais tu as raison, peut-être qu'un gourou de passage pourra te donner satisfaction.
wingover
Messages postés
21
Date d'inscription
lundi 15 décembre 2008
Statut
Membre
Dernière intervention
17 juin 2011
12 janv. 2009 à 15:21
12 janv. 2009 à 15:21
Et voilà, à force de chercher j'ai réussi avec cette requête:
Le résultat est bien celui attendu dans le poste 6 en utilisant les tables de ce même post.
Pour obtenir le résultat du post 10 il n'y a qu'à joindre deux fois la table user du post 1, une fois sur a.auteur et une fois sur dd.id_user.
Mais comme dit toto, si un gourou du MySQL passe par là et vois mieux je reste intéressé.
SELECT GROUP_CONCAT(dd.id_user), a.label, a.auteur, max( IF( a.auteur =4, IF( d.id_user =4, 2, 1 ) , 0 ) ) role FROM distrib d JOIN action a ON ( a.id = d.id_action ) JOIN distrib dd ON ( dd.id_action = d.id_action ) WHERE ( d.id_user =4 AND a.auteur <>4 ) OR ( a.auteur =4 AND d.id_user = dd.id_user ) GROUP BY a.id
Le résultat est bien celui attendu dans le poste 6 en utilisant les tables de ce même post.
Pour obtenir le résultat du post 10 il n'y a qu'à joindre deux fois la table user du post 1, une fois sur a.auteur et une fois sur dd.id_user.
Mais comme dit toto, si un gourou du MySQL passe par là et vois mieux je reste intéressé.