Récupérer deux fois le même champ, sur 2 lignes différentes

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : Récupérer deux fois le même champ, sur 2 lignes différentes

par furiouslol » 10 mars 2009, 08:44

La syntaxe de jointure avec le JOIN est la plus correcte, mais il me semble aussi, mais je ne suis pas sur, que la jointure dans le where est une syntaxe considérée comme ancienne et reste autorisée dans la plupart des SGBD mais pas tous ... Il se peut aussi que cet jointure dans le where (jointure non-explicite) soit abandonnée dans le futur

Quelqu'un a t'il des infos la dessus ? (j'ai lu des "on dit" mais rien d'officiel)

par Sékiltoyai » 10 mars 2009, 01:11

Le JOIN force le SGBD à organiser correctement les jointures ainsi que les conditions de jointure. Si elles sont laissées dans le WHERE, l'optimisation est laissée à la responsabilité du SGBD.
Donc l'utilisation des JOIN est bien plus propre, mais il faut tout de même savoir la faire correctement.

par Shrell » 09 mars 2009, 20:06

Au risque de paraitre abrupt et étroit d'esprit : parce que c'est comme ça :langue:
J'aurais aimé te sortir un comparatif chiffré de performances, mais n'en trouvant pas, j'en conclus que les performances sont identiques (à mon grand dam d'ailleurs, c'est tout un dogme qui s'écroule ^^)
Cependant, le JOIN est fait pour la jointure, et le WHERE pour le filtrage, séparer les deux permet donc d'être plus clair et de mieux s'y retrouver, un peu dans le même esprit qu'il faut sortir les informations de présentation du HTML pour n'y laisser que la sémantique ;)
Après, certains préfèrent laisser les conditions de jointure dans le WHERE, c'est selon l'humeur ;)
mais je persiste: c'est pas beau et c'est pas fait pour

par VaN » 09 mars 2009, 18:08

Effectivement ta méthode fonctionne bien.

Pourrais-tu développer pourquoi les liaisons entre tables se font avec des JOIN et non pas des WHERE ?

par Shrell » 09 mars 2009, 15:02

Non tu peux utiliser un alias de champ :
$message = getDataFromQuery(sprintf("SELECT msg_id, userFrom.user_login AS loginFrom, userTo.user_login AS loginTo, msg_datetime, msg_title, msg_content, msg_statut 
        FROM messages AS msg 
        LEFT JOIN users AS userFrom ON msg.msg_from_id=userFrom.user_id 
        LEFT JOIN users AS userTo ON msg.msg_to_id=userTo.user_id 
        WHERE msg_id = '%d'", 
        $clean["msg_id"]));
Et au risque de me répéter, les jointures se font à l'aide de la clause ON, pas dans la clause WHERE ;)

Récupérer deux fois le même champ, sur 2 lignes différentes

par VaN » 09 mars 2009, 14:50

Bonjour,

J'ai une table MESSAGES, et une TABLES USERS :

Code : Tout sélectionner

CREATE TABLE `messages` ( `msg_id` int(11) NOT NULL auto_increment, `msg_pc_id` int(11) NOT NULL, `msg_from_id` int(11) NOT NULL, `msg_to_id` int(11) NOT NULL, `msg_datetime` datetime NOT NULL, `msg_title` varchar(200) NOT NULL, `msg_content` text NOT NULL, `msg_statut` tinyint(4) NOT NULL, PRIMARY KEY (`msg_id`), KEY `msg_from_id` (`msg_from_id`), KEY `msg_to_id` (`msg_to_id`), KEY `msg_statut` (`msg_statut`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ; CREATE TABLE `users` ( `user_id` int(11) NOT NULL auto_increment, `user_login` varchar(100) NOT NULL, `user_pass` varchar(100) NOT NULL, `user_mail` varchar(100) NOT NULL, `user_statut` tinyint(4) NOT NULL, `user_activation_key` varchar(10) NOT NULL, `user_company` varchar(50) NOT NULL, `user_gender` enum('M','Mme','Mlle') NOT NULL, `user_firstname` varchar(50) NOT NULL, `user_lastname` varchar(50) NOT NULL, `user_address` varchar(150) NOT NULL, `user_zipcode` varchar(10) NOT NULL, `user_city` varchar(100) NOT NULL, `user_country` int(11) NOT NULL, `user_tel` varchar(20) NOT NULL, `user_mobile` varchar(20) NOT NULL, `user_allow_mails` tinyint(4) NOT NULL, PRIMARY KEY (`user_id`), KEY `user_statut` (`user_statut`), KEY `user_country` (`user_country`), KEY `user_allow_mails` (`user_allow_mails`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;
la table message stock 2 identifiants d'utilisateur : un pour savoir qui envoie le message, l'autre pour savoir qui le reçoit.

Et j'ai une fiche message, sur laquelle j'affiche les infos de ce message, et donc les login de la personne qui envoie le message, et celui de celle qui le reçoit.

Voici ma requête :
$message = getDataFromQuery(sprintf("SELECT msg_id, user_login, msg_datetime, msg_title, msg_content, msg_statut
		FROM ".$t["o_messages"].", ".$t["o_users"]." WHERE msg_from_id = user_id AND msg_to_id = user_id AND msg_id = '%d'", 
		$clean["msg_id"]));
Je récupère donc le user_login, en faisant une correspondance entre msg_from_id et user_id d'une part, et msg_to_id et user_id d'autre part. Mais comment faire pour afficher à la fois le login de l'envoyeur et celui du destinataire, puisqu'il s'agit du même nom de champ ?

Suis-je obligé de faire 2 requêtes différentes ?