Requete mysql jointure ou imbriquée

Julie13
Invité n'ayant pas de compte PHPfrance

30 mai 2010, 02:19

Bonsoir,
je travaille sur un inventaire de fruits en php/mysql.
Je souhaiterai avoir un peu d'aide sur mes requêtes mysql car ma méthode semble très fastidieuse, et je crois qu'il est possible de les simplifier avec des jointures ou des requêtes imbriquées.
Je vous explique :

J'ai 3 tables :
cagette (id_cagette, nom_cagette)
panier (id_panier, nom_panier, id_cagette)
fruit (id_fruit, nom_fruit, id_panier)

J'aimerai afficher ceci sous forme de tableau html :

| nom_cagette 1 | nom_panier 1 | nom_fruit 1 |
-----------------------------------| nom_fruit 2 |
------------------| nom_panier 2 | nom_fruit 3

| nom_cagette 2 | nom_panier 3 | nom_fruit 4 |
-----------------------------------| nom_fruit 5 |

Vous l'aurez compris :
> Je peux avoir plusieurs cagettes,
> Je peux avoir plusieurs paniers appartenant chacun à une cagette
> Je peux avoir plusieurs fruits appartenant à un seul panier

Du coup, j'utilise des réquêtes classiques pour faire des boucles dans des boucles du style :
SELECT * FROM cagette

Puis je fais :
SELECT * FROM panier WHERE id_panier=id_cagette
Donc ca m'affiche les paniers appartenant à la cagette.

Puis je termine par :
SELECT * FROM fruit WHERE id_fruit=id_panier

Comment puis-je optimiser ces requêtes en une seule ? Est-ce faisable ?
Merci pour votre aide,
Julie

Eléphant du PHP | 74 Messages

30 mai 2010, 04:38

Bonsoir,

Il faut que tu fusionnes tes 3 requêtes en une seule.
select * from cagette, panier, fruit where cagette.id_cagette = panier.id_cagette and panier.id_panier = fruit.id_panier
là, le souci c'est que l'ordre sera un peu au pif.

Il te suffit d'ajouter les order by dans le bonne ordre. 8-|

Ensuite, tu fais un traitement à l'affichage du type :
$oldPanier = $oldCagette = $oldFruit = "";

tant que(données sql) {
 si ($oldCagette != $sql["id_cagette"])
   affiche "|"$sql["cagette_nom"]"|"
  $oldCagette = $sql["id_cagette"])
 sinon affiche "---";

//meme type de condition à faire avec id_panier.
 si (...) { ... } sinon { }

//afficher directement le nom du fruit
affiche $sql["fruit_nom"]"|<br/>"
}

Julie13
Invité n'ayant pas de compte PHPfrance

30 mai 2010, 19:38

Salut datesta,
merci pour ton aide.
La requête mysql fonctionne, en revanche, je pense avoir un problème concernant l'affichage :

voici ce que je souhaite avoir :
http://yfrog.com/2ttablexj

Le code serait donc :
<table border="1" bordercolor="#000000">
	<tr>
		<td>Caguette 1</td><td>Panier 1</td><td>Fruit 1</td>
	</tr>
    <tr>
		<td>&nbsp;</td><td>Panier 2</td><td>Fruit 2</td>
	</tr>
    <tr>
		<td>&nbsp;</td><td>&nbsp;</td><td>Fruit 3</td>
	</tr>
</table>

<table border="1" bordercolor="#000000">
	<tr>
		<td>Caguette 2</td><td>Panier 3</td><td>Fruit 4</td>
	</tr>
    <tr>
		<td>&nbsp;</td><td>&nbsp;</td><td>Fruit 5</td>
	</tr>
    <tr>
		<td>&nbsp;</td><td>Panier 2</td><td>Fruit 6</td>
	</tr>
</table>
Au final j'ai cagette 1 qui se répète 3 fois.
Mon code :
$res = Requete("	SELECT * 
					FROM cagette, panier, fruit 
					WHERE cagette.id = panier.id_cagette 
					AND panier.id =  fruit.id_panier
					ORDER BY cagette.id",$connexion);
					
$oldcagette = $oldpanier =  $oldfruit= "";

while($d = bdd_fetch($res)) {
	if($oldcagette != $d["id"]) {
		echo "|".$d["nom_cagette"]."|";
  		$oldcagette = $d["id"];
}
else {
		echo "---";
}
+ les mêmes codes pour panier, mais ça répète également le tout.

Malheureusement, j'ai beau essayer, je n'arrive pas à avoir le résultat HTML mentionné ci-dessus.
Merci par avance, pour ton aide,
Julie

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

30 mai 2010, 22:16

Evite le "SELECT *" dans ta requête et précise le nom des champs que tu veux récupérer. En effet, quand tu fais appel à $d["id"] pour comparer la valeur à $oldcagette, tu n'a aucun moyen de savoir s'il s'agit bien du champ "id" de ta table cagette, ou si ce n'est pas celui de la table panier ou fruit...

En indiquant les noms des champs, tu peux même utiliser un alias pour les noms de champs qui seraient en double :
SELECT cagette.id as id_cagette, nom_cagette, panier.id as id_panier, ... FROM 
if($oldcagette != $d["id_cagette"]) { ...
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...