Requête imbriqué

Rechercher

Requête imbriqué

Par saturn1  -  7 reponses  -  Le 17/01/2009 23:52  -  Editer  - 

Bonjour je cherche à faire une requête imbriqué mais sans php. Voici les tables

CREATE TABLE `punch_categorie` (
  `categorie_id` int(2) NOT NULL AUTO_INCREMENT,
  `categorie_nom` varchar(255) DEFAULT NULL,
  PRIMARY KEY  (`categorie_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=8 ;
CREATE TABLE `punch_artiste` (
  `artiste_id` int(9) NOT NULL AUTO_INCREMENT,
  `artiste_nom` char(255) character SET utf8 DEFAULT NULL,
  `artiste_vus` int(9) NOT NULL DEFAULT '0',
  `artiste_image` char(255) collate utf8_bin DEFAULT NULL,
  `artiste_categorie_id` int(2) NOT NULL,
  PRIMARY KEY  (`artiste_id`),
  KEY `fk_pa_cat_id` (`artiste_categorie_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=49 ;
CREATE TABLE `punch_news` (
  `news_id` int(9) NOT NULL AUTO_INCREMENT,
  `news_titre` char(255) collate utf8_bin DEFAULT NULL,
  `news_contenu` text collate utf8_bin,
  `news_post` datetime DEFAULT NULL,
  `news_lecture` int(9) NOT NULL,
  `news_image` char(255) collate utf8_bin DEFAULT NULL,
  `news_artiste` int(9) NOT NULL,
  `news_auteur` int(9) NOT NULL,
  PRIMARY KEY  (`news_id`),
  KEY `fk_pn_auteur` (`news_auteur`),
  KEY `fk_pn_artiste` (`news_artiste`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=19 ;

 

Donc une table categorie , artiste et news. La news concerne un artiste, un artiste est dans une catégorie. Ce que je veux faire en une requête c'est sélectionner les news qui ont un certain id de categorie, comment faire sans php avec une boucle? Bien sur je peux mettre un champ idCategorie dans les news mais là n'est pas le but. Merci

 

Réponses apportées à cette discussion

Par Cyrano  -  Le 18/01/2009 08:14  -  Haut de page  - 

Salut Saturn1,

Je ne suis pas certain de comprendre pourquoi tu voudrais imbriquer des requêtes. Il me semble qu'une jointure serait suffisante et ce sera plus efficace.

D'autre part, tu as précisé "sans PHP" : je te dirais que le développement, c'est commencer par concevoir les requêtes en SQL avant même de songer à les intégrer dans du PHP ou dans quelque langage de programmation que ce soit du reste.

Voyons donc ton problème : identifier les news pour une catégorie donnée. On peut remarquer qu'il n'y a pas d'identifiant de catégorie dans la table `punch_news`. En revanche nous avons l'identifiant de l'artiste et dans la table punch_artiste un identifiant de catégorie : nous allons doncutiliser la transitivité pour retracer l'élément manquant de chaque news :

Voici une requête, nous allons la décortiquer ensuite :

SELECT n.news_id, n.news_titre, n.news_contenu, n.news_post, n.news_lecture, n.news_image, n.news_auteur
FROM punch_news AS n
JOIN punch_artiste AS a ON n.news_artiste = a.artiste_id
JOIN punch_categorie AS c ON a.artiste_categorie_id = c.categorie_id
WHERE c.categorie_id = 1;

Point par point :

  • Dans le SELECT, on ne met que les colones qui nous intéressent vraiment, rien de particulier là;
  • Dans le FROM, la table contenant les news :
  • Ensuite, les jointures avec un premier JOIN entre les news et l'artiste, puis entre l'artiste et la catégorie avec les conditions de jointure appropriées.
  • Enfin dans la clause WHERE avec l'identifiant de la catégorie souhaitée. Là, on a pas le choix de metre une valeur "en dur" : au moment d'intégrer ça coté PHP, tu pourras remplacer cette caleur par une variable.

Voilà, est-ce que ça répond à ta question ?

 
Par saturn1  -  Le 18/01/2009 12:07  -  Haut de page  - 

Cela répond tout à fait à ma question.

Je te remercie.

Sinon sur un tutoriel il disait d'utiliser LEFT JOIN pourqu'oi utilises tu JOIN?

Merci

 
Par Emacs  -  Le 18/01/2009 13:06  -  Haut de page  - 

LEFT JOIN et JOIN sont deux types de jointures différentes. Prenons deux tables A et B. La table A contient par exemple 10 enregistrements et la table B en contient 7 qui sont liés avec 7 des 10 enregistrements de A.

Si tu fais un LEFT JOIN entre A et B, alors MySQL te retournera 10 enregistrements. Pour les 3 enregistrements de A qui n'ont pas de relation avec B, tu obtiendras quand même des les champs de la table B avec des valeurs NULL dedans.

A l'inverse, la jointure JOIN est exclusive, c'est-à-dire qu'elle ne retourne que les enregistrements qui matchent la jointure. Ainsi, un JOIN entre A et B ne te retournera que les 7 enregistrements qui sont en relation dans les tables A et B.

++

 
Par saturn1  -  Le 18/01/2009 13:20  -  Haut de page  - 

Ok, merci !

Moi j'ai toujours fais des Left Join et cela ne ma jamais posé de problème.

 
Par Emacs  -  Le 18/01/2009 13:29  -  Haut de page  - 

Parce que tu avais certainement des objets ayant toujours des relations entre les tables que tu joignais.

 
Par saturn1  -  Le 18/01/2009 14:20  -  Haut de page  - 

Oui mais je veux dire même si cela sélectionne une entrée NULL

quand on lit le tableau de réception qui contient par exemple

array(

'NEWS 1',

'NEWS 2',

NULL

)

sa compte ou pas comme une entrée dans le tableau?

Je veux dire peut être que je sélectionnais des entrées NULL mais cela ne les affiche pas car cela vaut NULL?

 
Par Cyrano  -  Le 19/01/2009 18:21  -  Haut de page  - 

NULL ou l'absence de ligne dans une des tables revient à dire que la condition de jointure n'est pas satisfaite. Donc, à moins de faire une jointure dite "externe", tu n'obtiendras en sortie que les lignes ayant des correspondancesdes deux cotés de la jointure.

 

Je ne saurais trop te conseiller de te procurer un bouquin sur le SQL, il faudrait un cours complet sur les jointures et c'est quelque chose de vraiment puissant. Mais t'expliquer tout ça dans le détail sur un forum serait un peu long et assez peu efficace. Il existe peut-être du reste des tutos sur sqlpro.developpez.com, à vérifier.

 

Ajouter une réponse à la discussion

Seuls les membres connectés sont autorisés à poster dans les forums !

Identifiez-vous
Join |  ID/MDP? |