Comment simplifier une double requête par jointure?

WRInaute passionné
Bonjour,

Je cherche à simplifier une double requête par une jointure (si c'est possible) car il me semble que c'est plus rapide et je dois avoué avoir quelques difficultés :?

Code:
<?php
//on sélectionne les articles
$article = mysql_query("SELECT id, categorie_de_la_page FROM PAGE_DU_SITE ORDER BY id DESC ");

while($affiche = mysql_fetch_array($article))
 {
  echo ''.$affiche["id"].''.$affiche["titre_de_la_page"].'<br/>';
 
 //on sélectionne les catégories correspondantes
$cat = mysql_query('SELECT id, nom_sous_categorie FROM SOUS_CATEGORIE WHERE id='.$affiche['categorie_de_la_page'].'');

while($affiche1 = mysql_fetch_array($cat))
 {
 echo ''.$affiche1["id"].'-'.$affiche1["nom_sous_categorie"]).'';
 }
//on ferme la 1ere boucle while
 }
?>

Le champ "categorie_de_la_page" de la table "PAGE_DU_SITE" correspond au champ "id" de la table "SOUS_CATEGORIE" qui sont tout 2 des chiffres entier.
Ainsi : "categorie_de_la_page" est égal à "id" -> me ressort le bon nom de la catégorie correspondant à l'article.

Si vous avez quelques suggestions ...
Merci
 
WRInaute passionné
dorian53,

Peux tu stp nous expliquer la différence entre INNER et LEFT (dans mon cas j'utilise LEFT JOIN... et non INNER JOIN)
Merci par avance,

Anto
 
WRInaute discret
INNER JOIN te retourne uniquement les champs ou tu as une correspondance dans les 2 tables

Par exemple
Code:
SELECT * FROM Table1 INNER JOIN Table2 ON Table1.valeur=Table2.valeur

Tu n'obtiendras que les lignes ou valeur est égale dans Table1 et Table2

Alors que

Code:
SELECT * FROM Table1 LEFT JOIN Table2 ON Table1.valeur=Table2.valeur

La tu vas obtenir toutes les lignes de la table1, et les lignes de la table2 ou le champ valeur est égal à celui de table1. Dans le cas ou il n'est pas égale, les champs de table2 prendront la valeur nulle dans les résultats de la requête.
 
WRInaute passionné
Merci Miss Google :).

Même avec ton exemple + le lien je me fume les neurones .. ça va m'occuper 2/3 semaines ^^ !
 
WRInaute passionné
Re moi ^^,

Je suis presque parvenu à mes fins après mainte tentative mais un problème réside ...
Suite à ma requête, je construis 2 liens. L'un menant vers un article et l'autre vers la catégorie de l'article. Le "hic", c'est que tout deux utilisent un "id" et comme je ne suis pas habitué à ce style de requête .. bhin je suis largué :? .
Bref, dans la requête qui suis c'est l'id de la catégorie qui est pris en compte dans les 2 liens $affiche2["id"] et je ne sais pas comment y remédier ...
Code:
$teste2 = mysql_query("SELECT * FROM PAGE_DU_SITE INNER JOIN SOUS_CATEGORIE ON PAGE_DU_SITE.categorie_de_la_page=SOUS_CATEGORIE.id ORDER BY PAGE_DU_SITE.id DESC LIMIT 0,5");

while($affiche2 = mysql_fetch_array($teste2))
{
//Lien vers l'article
  echo '<a title="'.$affiche2["titre_de_la_page"].'" href="'.OptimiseUrl($affiche2["titre_de_la_page"]).'-'.$affiche2["id"].'.php">'.$affiche2["titre_de_la_page"].'</a>';
//lien vers la catégorie
 echo '<a title="'.$affiche2["nom_sous_categorie"].'" href="sous-categorie-'.$affiche2["id"].'-'.OptimiseUrl($affiche2["nom_sous_categorie"]).'.php">'.$affiche2["nom_sous_categorie"].'</a>';
}
Une suggestion ?

Merci
 
WRInaute accro
SELECT * c'est le mal. Et pour ta problématique, les alias sont tes amis (perso c'est pour ça que je n'appelles pas mes clés primaires avec le même nom, mais que je les préfixe avec le nom de la table) :

Code:
SELECT PAGE_DU_SITE.titre_de_la_page, PAGE_DU_SITE.id as id_page, SOUS_CATEGORIE.nom_sous_categorie, SOUS_CATEGORIE.id as id_sous_categorie  FROM PAGE_DU_SITE INNER JOIN SOUS_CATEGORIE ON PAGE_DU_SITE.categorie_de_la_page=SOUS_CATEGORIE.id ORDER BY PAGE_DU_SITE.id DESC LIMIT 0,5

Une fois avoir fait ça, tu peux utiliser id_page et id_sous_categorie
 
WRInaute passionné
Oki, merci UsagiYojimbo :D , je vais essayer ça.

Donc, quand on fait une jointure et que si sur celle ci 2 champs portent le même nom, il faut systématiquement utiliser les alias...c'est méga chiant comme requête :lol: !

Par apport à ma double requête en haut de poste, j'y gagne vraiment quelque part ou ça fait juste plus fun ?
 
WRInaute passionné
tryan a dit:
Par apport à ma double requête en haut de poste, j'y gagne vraiment quelque part ou ça fait juste plus fun ?

Tu y gagnes et c'est une utilisation ordinaire, ne pas faire la jointure et gérer ça manuellement est contre nature.

Si tu avais 100 catégories, tu aurais fait 101 requêtes (sans oublier le traitement PHP annexe : while, $var, ...).
Là, une seule optimisée par la base de données.
 
WRInaute passionné
Oki, tout semble fonctionner parfaitement :).

Merci bien pour tout ses renseignements fort utiles mais haut combien compliqué quand même ;).
 
WRInaute passionné
Re moi,

Peut on également "jointer" ^^ 4 requêtes disposant toutes d'un champ égales (chiffres entier identiques dans les 4 tables) ?
 
WRInaute discret
Oui, si tu as une condition de jointure (champ égal dans les 4 tables), tu peux joindre 4 tables sans problème. C'est valable pour n tables si ta condition de jointure est valable sur n table.
 
WRInaute passionné
Tu peux même JOINTER plusieurs fois la même table...

(si si, ça a une utilité.... quand on cherche bien... et franchement c'est surpuissant)
 
WRInaute passionné
Re re moi ^^,

Bon, j'essaye d'intégrer une troisième table dans ma jointure et je dois m'y prendre comme un manche parce que ça marche pas ... ça m'énerve les jointures ^^.
Code:
SELECT PAGE_DU_SITE.titre_de_la_page, PAGE_DU_SITE.id as id_page, SOUS_CATEGORIE.nom_sous_categorie, SOUS_CATEGORIE.id as id_sous_categorie  FROM PAGE_DU_SITE INNER JOIN SOUS_CATEGORIE ON PAGE_DU_SITE.categorie_de_la_page=SOUS_CATEGORIE.id ORDER BY PAGE_DU_SITE.id DESC LIMIT 0,5
La, j'essaye d'intégrer en jointure une table dont le nom est "CATEGORIE" comportant un champ "id" correspondant aux champ SOUS_CATEGORIE.id et PAGE_DU_SITE.categorie_de_la_page.

Donc , dans la requête j'ajoute CATEGORIE.id as id_categorie mais alors après ... je suis largué à partir du FROM :?

Une suggestion siouplé
 
WRInaute passionné
C'est pas très clair. Pour t'aider, tu peut schématiser tes tables et tes liens (de la même façon que dans Access tu sais)
 
WRInaute passionné
Bon, je fais au mieux ^^

--CATEGORIE---|---------SOUS_CATEGORIE-----------|--------PAGE_DU_SITE----------|
--id--|--nom----|--id--|---nom_categorie_principal--|--id--|--categorie_principal---|
--1---|--bla-----|--7---|------------------1-------------- |--9---|---------1-----------------|

Jointure de : (CATEGORIE) id = (SOUS_CATEGORIE) nom_categorie_principal = (PAGE_DU_SITE) categorie_principal
Soit, nom_categorie_principal et categorie_principal correspondent toujours à id de la table CATEGORIE

Code:
$query1 = mysql_query("SELECT 
CATEGORIE.id as cat_id,
CATEGORIE.nom,
SOUS_CATEGORIE.id as sous_cat_id,
SOUS_CATEGORIE.nom_categorie_principal,
SOUS_CATEGORIE.nom_sous_categorie,
PAGE_DU_SITE.id as pds_id,
PAGE_DU_SITE.categorie_principal
FROM \ici je sèche\
LIMIT 1,7");

Le but étant d'afficher les catégories suivit des sous catégories correspondante aux catégories suivit des pages correspondantes aux sous catégories et le tout en évitant une triple requête :lol: .
 
WRInaute passionné
Le but étant d'afficher les catégories suivit des sous catégories correspondante aux catégories suivit des pages correspondantes aux sous catégories et le tout en évitant une triple requête .
OK, par contre, dans ce cas, il ne faut pas "relier" tes pages à l'id de la categorie principale mais bien à l'id de la sous catégorie (j'ai corrigé dans le code)


Un petit conseil, nomme différemment tes champs id (tu peux les nommer de la façon suivante:
id_nomtable (ça t'évitera d'avoir des allias dans ta requête SQL et pour commencer, ce sera plus clair et plus compréhensible.

Ensuite tu obtiendra ça:
Code:
-----------CATEGORIE-------------------|
--categorie_id--|--categorie_nom----|
--1---------------|---bla-----------------|

|---------SOUS_CATEGORIE-----------------------------|
|--souscategorie_id--|---souscategorie_categorieid |
|--7---------------------|------------------1-------------- |

|--------PAGE_DU_SITE-----------------|
|--page_id--|--page_souscategorieid|
|--9----------|---------7-----------------|



Code:
SELECT 
CATEGORIE.categorie_id,CATEGORIE.categorie_nom,
SOUS_CATEGORIE.souscategorie_id,SOUS_CATEGORIE.souscategorie_categorieid ,
PAGE_DU_SITE.page_id,PAGE_DU_SITE.page_souscategorieid 
FROM CATEGORIE 
INNER JOIN SOUS_CATEGORIE ON SOUS_CATEGORIE.souscategorie_categorieid=CATEGORIE.categorie_id 
INNER JOIN PAGE_DU_SITE ON PAGE_DU_SITE.page_souscategorieid=SOUS_CATEGORIE.souscategorie_id
LIMIT 1,7");

ah... et un autre petit conseil. Tous mes champs... mes noms de tables etc sont en minuscule (comme ça, en majuscule je n'ai que la syntaxe MySQL... c'est plus clair aussi!

Dis moi si ça fonctionne.
 
WRInaute passionné
Merci Anto1982 mais ça ne marche pas.

Je crois que ça provient des champs que tu as mis et qui n'existe pas genre "categorie_id" et autres.

Le code sous sa forme presque qu'initiale si ça peut aider donc m'aider ^^:
Code:
<?
//Sélection des catégories 
$query0 = mysql_query("SELECT id,nom_categorie FROM CATEGORIE ORDER BY rang ASC LIMIT 1,7");

while($categorie = mysql_fetch_array($query0))
 {
$id_categorie=$categorie["id"];
######Ici le résultat de la boucle#######

//Sélection des sous catégories
$query1 = mysql_query("SELECT id,nom_categorie_principal,nom_sous_categorie FROM SOUS_CATEGORIE WHERE nom_categorie_principal='".mysql_real_escape_string($id_categorie)."' ORDER BY rang ASC LIMIT 0,05");

while($souscategorie = mysql_fetch_array($query1))
 {
$id_de_la_sous_categorie=$souscategorie["nom_categorie_principal"];
######Ici le résultat de la boucle#######

//Sélection des pages
$query2 = mysql_query("SELECT id,categorie_principal,categorie_de_la_page,titre_de_la_page,description_de_la_page FROM PAGE_DU_SITE WHERE categorie_de_la_page='".mysql_real_escape_string($id_de_la_sous_categorie)."' AND titre_de_la_page != '' ORDER BY rang ASC LIMIT 0,05");

while($pagedusite = mysql_fetch_array($query2))
 {
######Ici le résultat de la boucle#######
 }
 }
 }
mysql_close();
?>
Daprès ce que j'ai comprit, il me faut des allias sur tout mes champs "id" pour pouvoir les afficher correctement et utiliser les bon nom de champ ... ce qui ,si je ne me plante pas, donne un début de requête comme cela :
Code:
$query1 = mysql_query("SELECT
CATEGORIE.id as cat_id,
CATEGORIE.nom_categorie,
CATEGORIE.rang,

SOUS_CATEGORIE.id as sous_cat_id,
SOUS_CATEGORIE.nom_categorie_principal,
SOUS_CATEGORIE.nom_sous_categorie,

PAGE_DU_SITE.id as page_id,
PAGE_DU_SITE.categorie_principal,
PAGE_DU_SITE.categorie_de_la_page,
PAGE_DU_SITE.titre_de_la_page,
PAGE_DU_SITE.description_de_la_page 

FROM /******je seche*********/
INNER JOIN /******je re seche**********/");
De plus, la première requête utilise : ORDER BY rang ASC LIMIT 1,7 alors que les 2 autres utilisent ORDER BY rang ASC LIMIT 0,05 .

Bref, c'est vraiment très compliqué les jointures je trouve...
 
WRInaute passionné
il faut que tu travailles avec les ID de tes tables (techniquement, ton truc peut marcher comme ça mais c'est source d'erreur pour plus tard.
Dans ta table SOUS_CATEGORIE, il faut donc remplacer ton champ "nom_categorie_principal" par "id_categorie_principale" (modifié en rouge)

Pareil, si tu veux lier ta page a ta sous catégorie qui elle meme est liée à ta categorie, il faut spécifier dans ta table PAGE_DU_SITE non pas le nom de la categorie mais bien l'id de la sous catégorie (j'apelle ce champs souscategorie_id... en vert dans mon code)

$query1 = mysql_query("
SELECT

CATEGORIE.id AS cat_id,
CATEGORIE.nom_categorie,
CATEGORIE.rang,

SOUS_CATEGORIE.id AS sous_cat_id,
SOUS_CATEGORIE.id_categorie_principale,
SOUS_CATEGORIE.nom_sous_categorie,

PAGE_DU_SITE.id AS page_id,
PAGE_DU_SITE.categorie_principal, <= inutile car tu peux récuperer cette info dans la première table grace à la jointure!
PAGE_DU_SITE.souscategorie_id,
PAGE_DU_SITE.titre_de_la_page,
PAGE_DU_SITE.description_de_la_page

FROM CATEGORIES
INNER JOIN SOUS_CATEGORIE ON SOUS_CATEGORIE.id_categorie_principale=CATEGORIE.id
INNER JOIN PAGE_DU_SITE ON PAGE_DU_SITE.souscategorie_id=SOUS_CATEGORIE.id
");

essayes simple pour commencer (ne mets pas de LIMIT, de ORDER ASC, etc.)

De toute façon (SI j'ai bien compris ce que tu veux faire, c'est impossible en l'état actuel, il faut que tu revoies la structure de tes tables et de tes champs. Pour faire des jointures, il faut être capable de lier la table A à la table B qui elle meme est liée à ta table C:

A=>B=>C

Pour ça, tu dois avoir un champ qui contien la meme inf dans la table A et B pui un autre champs qui te fait le lien entre la table B et C... C'est comme une cascade.
 
Discussions similaires
Haut