Problème avec INNER JOIN et LEFT OUTER JOIN

Petit nouveau ! | 2 Messages

06 sept. 2011, 11:53

Bonjour a tous, j'ai un petit problème avec une requête pour un moteur de recherche.
composition de la BDD
professeur: id nom prenom
etablissement: numero_u denomina patronym,localite,code_pos
enseigne_etablissement: profid (id de professeur) rne(numero_u de etablissement)
enseigne_niveau: profid (id de professeur) niveauid (id de niveau)
enseigne_discipline: profid (id de professeur) disci (id de discipline)
discipline: id nom
niveau: id nom

Et voici la requete
if(isset($_POST['rechercher'])){
/*echo $_POST['nom'];
echo $_POST['prenom'];
echo $_POST['matiere'];
echo $_POST['niveau_etablissement'];
echo $_POST['nom_etablissement'];
echo $_POST['ville'];*/

	 $req = "SELECT  professeur.*,
					 etablissement.*,
					 enseigne_etablissement.*,
					 enseigne_niveau.*, 
					 enseigne_discipline.*,
					 discipline.*,
					 niveau.*
					 FROM professeur
				         INNER JOIN enseigne_discipline on enseigne_discipline.profid = professeur.id 
					 INNER JOIN enseigne_discipline on enseigne_discipline.disci = discipline.id 
					 INNER JOIN enseigne_niveau on enseigne_niveau.profid = professeur.id 
					 INNER JOIN enseigne_niveau on enseigne_niveau.niveauid = niveau.id 
					 INNER JOIN enseigne_etablissement on enseigne_etablissement.profid = professeur.id 
					 INNER JOIN enseigne_etablissement on enseigne_etablissement.rne = etablissement.numero_u ";
	 if($_POST['nom']!=''){
		$wheres[] = "professeur.nom = '{$_POST['nom']}' ";
	 }
	 if($_POST['prenom']!=''){
		$wheres[] = "professeur.prenom = '{$_POST['prenom']}' ";
	 }
	 if($_POST['matiere']!=''){
		$wheres[] = "discipline.nom = '{$_POST['matiere']}' ";
	 }
	 if($_POST['niveau_etablissement']!=''){
		$wheres[] = "niveau.nom = '{$_POST['niveau_etablissement']}' ";
	 }
	 if($_POST['nom_etablissement']!=''){
		$wheres[] = "etablissement.patronym = '{$_POST['nom_etablissement']}' ";
	 }
	 if($_POST['ville']!=''){
		$wheres[] = "(etablissement.localite = '{$_POST['ville']}' OR etablissement.code_pos = '{$_POST['ville']}') ";
	 }
	 $where_q = "";
	 foreach($wheres as $where){
		if($where_q == ""){
			$where_q = "WHERE ". $where;
		}else {
			$where_q .= "and ".$where;
		}	
	 }
	$req .= " ".$where_q;
	echo $req;
	 $req_nom = mysql_query($req);
	 
	 while ($nom = mysql_fetch_assoc($req_nom))
            {
			echo $nom['nom']."<br />";
			echo $nom['prenom']."<br />";
			echo $nom['disci']."<br />";
			echo $nom['rne']."<br />";
			echo $nom['niveauid']."<br />";
			
			}
}
else{}
Lorsque je lance une recherche il m'affiche bien la requête (echo $req) mais il y a une erreur
Warning: mysql_fetch_assoc(): supplied argument is not a valid MySQL result resource in D:\wamp\www\corps_anuaire_recherche.php on line 114
Je ne vois pas d'où cela peut venir, quelqu'un pourrai t'il m'aider?

ViPHP
ViPHP | 2577 Messages

06 sept. 2011, 12:03

Après le mysql_query affiche mysql_error() pour avoir l'erreur.

Petit nouveau ! | 2 Messages

06 sept. 2011, 12:08

cela me donne
Not unique table/alias: 'enseigne_discipline'

Edit: au final je me suis passé des inner join j'ai fait des conditions manuelles et un group by nom prenom .
 $req = "SELECT  professeur.nom,professeur.prenom,professeur.id,
					 etablissement.*,
					 enseigne_etablissement.*,
					 enseigne_niveau.*, 
					 enseigne_discipline.*,
					 discipline.*,
					 niveau.*
					 FROM professeur,etablissement,enseigne_etablissement,enseigne_niveau,enseigne_discipline,discipline,niveau
					 WHERE enseigne_discipline.profid = professeur.id 
					 AND enseigne_discipline.disci = discipline.id  
					 AND enseigne_discipline.profid = professeur.id
					 AND  enseigne_niveau.niveauid = niveau.id
					 AND  enseigne_etablissement.profid = professeur.id
					 AND  enseigne_etablissement.rne = etablissement.numero_u ";

ViPHP
ViPHP | 2577 Messages

06 sept. 2011, 15:07

Le problème venait des lignes :
INNER JOIN enseigne_discipline on enseigne_discipline.profid = professeur.id
INNER JOIN enseigne_discipline on enseigne_discipline.disci = discipline.id

Tu demandais à utiliser 2 fois la table "enseigne_discipline"

Edit, peut être :
INNER JOIN enseigne_discipline on enseigne_discipline.profid = professeur.id
INNER JOIN discipline on enseigne_discipline.disci = discipline.id

Mammouth du PHP | 19672 Messages

06 sept. 2011, 21:21

Utilise des alias plus court, ce sera plus facile à lire et effectivement, tu avais des manques notables dans tes conditions de jointures en utilisant les mauvaises tables sur certaines.

Autre point, pour ta clause WHERE, tu pourrais simplifier avec implode au lieu d'une boucle. Ça donnerait à peu près ceci :
<?php
//...
    $req = "SELECT
              pr.*,
              et.*,
              ee.*,
              en.*,
              ed.*,
              di.*,
              ni.*
            FROM professeur pr
              INNER JOIN enseigne_discipline    ed ON ed.profid   = pr.id
              INNER JOIN discipline             di ON ed.disci    = di.id
              INNER JOIN enseigne_niveau        en ON en.profid   = pr.id
              INNER JOIN niveau                 ni ON en.niveauid = ni.id
              INNER JOIN enseigne_etablissement ee ON ee.profid   = pr.id
              INNER JOIN etablissement          et ON ee.rne      = et.numero_u ";
    if($_POST['nom']!=''){
        $where[] = "pr.nom      = '{$_POST['nom']}'";
    }
    if($_POST['prenom']!=''){
        $where[] = "pr.prenom   = '{$_POST['prenom']}'";
    }
    if($_POST['matiere']!=''){
        $where[] = "di.nom      = '{$_POST['matiere']}'";
    }
    if($_POST['niveau_etablissement']!=''){
        $where[] = "ni.nom      = '{$_POST['niveau_etablissement']}'";
    }
    if($_POST['nom_etablissement']!=''){
        $where[] = "et.patronym = '{$_POST['nom_etablissement']}'";
    }
    if($_POST['ville']!=''){
        $where[] = "(et.localite = '{$_POST['ville']}' OR et.code_pos = '{$_POST['ville']}')";
    }
    // La clause WHERE si un des paramètre a été fourni :
    $where_q = (count($where) > 0) ? "WHERE ". implode(" AND ", $where) : null;
    $req .= $where_q;
    echo $req;
//... etc...
Pas plus clair comme ça ?
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe: