Requete MySQL

HommeCocoa

Membre actif
3 Janvier 2003
173
0
Vevey - Suisse
Bonjour,

J'ai un petit soucis avec une requete MySQL.

Tout d'abords, j'ai créé 2 bases de données, une tb_membres contenant des membres et l'autre
tb_groupes contenant des groupes auquel les membres peuvent faire partie.

Il faut noter que chaque membre peut faire partie de plusieurs groupes ou aucun

Entre les deux, pour lier tout ça j'ai créer une base de liaison tb_join_membres_groupes.

Un moment donné je souhaites avoir une requête qui va chercher tous les membres appartenant à certains groupes.

Pour un seul groupe, c'est super simple je fais:

Bloc de code:
SELECT * FROM tb_membres,tb_groupes,tb_join_membres_groupes
WHERE tb_membres.ID = tb_join_membres_groupe.ID_membre
AND tb_groupes.ID = tb_join_membres_groupe.ID_groupe
AND tb_groupes.ID = '$id_du_groupe_choisi'

Jusqu'ici tout vas bien, mais alors pour en selectionner plusieur à la fois, c'est un casse tête que je n'arrive pas à résoudre.

J'ai par exemple essayé de remettre à la suite des AND tb_groupes.ID = autre_groupe, mais il ne me retourne rien et je comprend bien pourquoi mais je n'ai pas d'idée comment faire d'autre.
J'ai aussi essayé de mixé les AND et les OR mais je comprend pas vraiment la priorités des opérateurs dans ce cas...

Si quelqu'un y voit clair, j'écoute volontiers ses conseils! :rose:

Merci à tous,
David
 
Bonjour :)

Essaye avec ça :

Bloc de code:
SELECT * FROM tb_membres,tb_groupes,tb_join_membres_groupes
WHERE tb_membres.ID = tb_join_membres_groupe.ID_membre
AND tb_groupes.ID = tb_join_membres_groupe.ID_groupe
AND (tb_groupes.ID = '$id_du_groupe_choisi1' OR tb_groupes.ID = '$id_du_groupe_choisi2' OR tb_groupes.ID = '$id_du_groupe_choisi3' OR ... )

Si tu veux faire ça dynamiquement, passe par une boucle for dans ton PHP, du genre :

Bloc de code:
for ($i=0; $i < $nb_groupes ; $i++){
if ($i != $nb_groupes)
$groupes .= "tb_groupes.ID = id_du_groupe OR ";
else
$groupes .= "tb_groupes.ID = id_du_groupe OR ";
}

Et tu insères ensuite $groupes dans ta requête.

En espérant que ça t'aidera.
 
Bloc de code:
SELECT * 
FROM tb_membres t1
JOIN tb_join_membres_groupes t2 ON (t1.ID=t2.ID_membre)
JOIN tb_groupes t3 
ON (t2.ID_groupe=t3.ID
AND t3.ID IN (1,2,3))

Ou tu sélectionnes ici les groupes 1, 2 et 3
 
Bonjour,


J'ai par exemple essayé de remettre à la suite des AND tb_groupes.ID = autre_groupe, mais il ne me retourne rien et je comprend bien pourquoi mais je n'ai pas d'idée comment faire d'autre.
J'ai aussi essayé de mixé les AND et les OR mais je comprend pas vraiment la priorités des opérateurs dans ce cas...

Normal qu'en cumulant les "AND", tu n'aies aucun résultat.
Si tu fais tb_groupes.ID=1 AND tb_groupes.ID=2, ça ne marchera jamais car tu ne peux pas avoir un groupe égal à 1 ET à 2.

Par contre, tu peux avoir :
Bloc de code:
SELECT *
...
WHERE
...
AND (tb_groupes.ID=1 OR tb_groupes.ID=2)

Les parenthèses sont ici importantes, ce sont elles qui donne la priorité à l'opération.

Remarque que la dernière ligne est également équivalente à
Bloc de code:
AND (tb_groupes.ID IN (1,2))
 
Bonjour,

Merci à tous pour vos réponses.
J'ai fais quelques petits essais aujourd'hui.
J'ai mis en ouvre cette solution:

Bloc de code:
SELECT * FROM tb_membres,tb_groupes,tb_join_membres_groupes
WHERE tb_membres.ID = tb_join_membres_groupe.ID_membre
AND tb_groupes.ID = tb_join_membres_groupe.ID_groupe
AND (tb_groupes.ID = '$id_du_groupe_choisi1' OR tb_groupes.ID = '$id_du_groupe_choisi2' OR tb_groupes.ID = '$id_du_groupe_choisi3' OR ... )

Le problème est maintenant qui se une personnes appartient à 3 groupes, elle apparaîtra 3 fois dans la liste...

Car en faisant les jointures ça va la tripler à cause qu'elle se trouve 3 fois dans table_join_membre_groupe...

il doit exister une possibilité de regler ça avec le DISTINCT sachant que je veux prendre tous les champs avec * ?

Merci d'avance
 
Du coup je tente de travailler avec le DISCTINCT mais comme j'ai quand même besoin de tous les champs, ça me donne un truc dans le genre

Bloc de code:
$req = "SELECT DISTINCT($this->tableMembres.ID), * " .   ici la suite des conditions.

mais il semble que la synthaxe

Bloc de code:
 DISTINCT(tb_membre.ID), *

ça joue pas...
 
La clause DISTINCT s'applique à l'ensemble des champs.
Donc il est normal que si tes informations sont différentes, tu obtiennes 2 fois les mêmes noms.

Sinon, pour la condition ou tu n'utilises pas de groupe, essaye plutôt ma syntaxe, ça devrait marcher sans problème. Dans le IN (), tu mets un "0" qui ne correspond à aucun groupe.

Ca te donnera un IN(0), ça devrait fonctionner.

Pour regrouper par nom, tu peux utiliser la clause "group by" qui te permettra de ne conserver qu'un seul nom par ligne. Par contre, évidemment, tu n'auras pas l'ensemble des groupes d'un membre.
 
Bonjour,

Bladrak: malheureusement, le DISCTINCT(*) ne marche pas non plus...

SuperCed: ta solution me plaît beaucoup car déjà elle est très propre avec les JOIN et IN au lieu de l'immense clause WHERE que j'ai faite, dorénavant je coderais comme ça.

Par contre pour cette requête comme elle est générée dynamiquement, à vrai dire, ça m'embête un peu de toute la réécrire.

Mais j'ai retenu ta solution du GROUP BY qui marche bien dans mon cas. Car je ne veux jamais afficher tous les groupes d'une personnes mais simplement afficher toutes les personnes (et ceci qu'une seule fois) appartenant au groupes sélectionné par des checkbox.

Donc là en ajoutant avec le ORDER un GROUP BY nom,prenom, ça fait l'affaire!

J'y pense, cette solution offre un bug pour les personnes ayant le même nom et prenom!
Je vais faire un GROUP BY ID,nom,prenom, ça devrait faire l'affaire?
 
Bah, le code php est facilement adaptable :
Bloc de code:
$in = (0
for($i=0;$i<count($tabGroupe);$i++) {
    $in .= ','.$tabGroupe[$i];
}
$in .= ')';

$sql = "SELECT * 
FROM tb_membres t1
JOIN tb_join_membres_groupes t2 ON (t1.ID=t2.ID_membre)
JOIN tb_groupes t3 
ON (t2.ID_groupe=t3.ID
AND t3.ID IN ".$in.")
GROUP BY ID,nom,prenom";
Attention, dans ce cas, le groupe 0 n'existe pas, c'est juste pour que la requête soit toujours cohérente.
Si tu as un groupe 0, alors change le "0" par "-1".
 
Oui c'est vrai que c'est quand même beaucoup plus élégant ça!!

Et surtout merci d'avoir carrément réécrit en entier ma requête, je vais aussi essayer de la réécrire une fois pour bien l'intégrer.

Merci beaucoup pour votre aide, c'est super sympa et ça m'a bien dépanné. :rose: