Problème de requete SQL

Problème de requete SQL - SQL/NoSQL - Programmation

Marsh Posté le 06-06-2011 à 11:43:01    

Bonjour,
 
Je crée un réseaux social pour mon projet de fin d'année.
 
J'ai un problème au niveau de mes messages privées, plus particulièrement à l'affichage.
 
Je voudrais que dans ma boite de réception les dossiers soit sous forme d'auteur (un peu comme les sms de l'Iphone).
 
Cela marche à condition qu'une seul personne converse, si l'autre personne répond, dans ma boite de réception je vais avoir 2X le même dossier.
 
J'ai un peu de mal a expliquer alors voici un exemple :
 
Toto envoi un message privé à Titi.
 
Toto voit bien son dossier dans la boite de réception et Titi aussi ( et cela même si toto envoi 2 messages)
Quand titi à répondu un 2éme dossier se créé avec le même nom d'auteur et le même contenu.
 
Voici ma table :
 
tbl_mp:
-id_mp_to
-id_mp-from
-message
-date_mp
 
Et la partie de ma requête SQL qui je pense et fausse:
 

Code :
  1. $recherche_auteurs = mysql_query("select distinct id_mp_from,id_mp_to from tbl_mp WHERE id_mp_from ='".$_SESSION['id']."' OR id_mp_to ='".$_SESSION['id']."'" );


Et la suite au cas ou
 

Code :
  1. print('<table border="2" align="center"><tr><th>Auteur</th><th>Date</th></tr>');
  2. while ($auteurs = mysql_fetch_assoc($recherche_auteurs)){
  3.  $recherche_auteur= mysql_query("select distinct pseudo_user,id_user from tbl_user WHERE (id_user = '".$auteurs['id_mp_to']."' OR id_user = '".$auteurs['id_mp_from']."') AND id_user != '".$_SESSION['id']."'" );
  4.  $auteur= mysql_fetch_array($recherche_auteur);
  5.  if(nouveau_mp($_SESSION['id'],$auteur['id_user']) != false ){
  6.   print('<tr><td>Nouveaux méssage</td>');
  7.  }else{
  8.   print('<tr><td>Pas de nouveaux méssage</td>');
  9.  }
  10.  print('<td><a href="boite.php?id='.$auteur['id_user'].'">'.$auteur['pseudo_user'].'</a></td></tr>');
  11. }
  12. print('</table>');


 
Le but de ma requete et de renvoyer le pseudonyme de la personne avec qui nous conversons Le probleme c'est que si la conversation ce fait , il y aura 2X le pseudo
 
Si vous avez besoin de ma page en entière je la mettrai pas de souci
 
Merci de votre aide
 
Cordialement ,
 
Inoxis91

Reply

Marsh Posté le 06-06-2011 à 11:43:01   

Reply

Marsh Posté le 06-06-2011 à 14:31:35    

C'est le genre de resultats qu'on obtien quand il y a un produit cartesien qui traine quelque part (en gros il manque une ou plusieurs condition dans le Where qui reduisent le nombre de réponses).
 
Le plus facil dans ton cas est d'avoir une table Messages avec le détail du message (ID, date, heure, contenu, ConversationID), le ConversationID te permet de savoir dans quel conversation mettre le message (conversation peu etre soit un post dans un forum ou un message privé), tu as une autre table Participants avec la liste des participant a chaque message (MessageID, UserID).
 
Avec ca tu devrais pouvoir gerer des converstation avec un nombre de particiant qui peu varier de message en message.
Tu sais aussi facilement retrouver les messages envoyé par une personne.


Message édité par Oliiii le 06-06-2011 à 14:32:45
Reply

Marsh Posté le 06-06-2011 à 14:40:07    

C'est ce que j'ai fait mais avec des noms différents ma table message ce nomme tbl_mp ( je ne gére que des message priver)
Et ma table participants c'est en faite ma table user...
C'est message ne peuvent être que entre 2 utilisateurs seulement

Reply

Marsh Posté le 06-06-2011 à 14:56:16    

Pour vous aider a mieux comprendre mon problème:) :  
Contenue de ma table méssage :
http://img821.imageshack.us/img821/8127/basefr.th.png
 
Résultat sur le site :
http://img13.imageshack.us/img13/3655/boiter.th.png
 
Comme on peut le voir Floflo y est en 2 fois au lieux de une

Reply

Marsh Posté le 06-06-2011 à 16:43:05    

Il faudrait faire :

Code :
  1. SELECT DISTINCT id_correspondant FROM(
  2.  (SELECT id_mp_from AS id_correspondant FROM tbl_mp WHERE id_mp_to ='".$_SESSION['id']."')
  3.  UNION
  4.  (SELECT id_mp_to FROM tbl_mp WHERE id_mp_from ='".$_SESSION['id']."')
  5. )


On agrège les MPs dans les deux sens avant d'appliquer le distinct.
 
A part ça, ton code n'est pas tellement optimisé : tu pourrais directement récupérer toutes les infos sur les MP directement dans cette requête, plutôt que refaire une requête dans une boucle après.
Au pire, utilise une requête préparée : tu prépares en dehors de la boucle et tu appelles dans la boucle. C'est bien plus efficace.

Reply

Marsh Posté le 06-06-2011 à 16:44:22    

C'est normal que le resultat soit la 2x, c'est a cause du OR.
Le user est une fois dans le FROM et une fois dans le TO.
 
Tu devrais pouvoir t'en sortir en fesant un "SELECT DISTINCT CASE WHEN id_mp_from = '".$_SESSION['id']."' THEN id_mp_to ELSE id_mp_from END id_mp  
from tbl_mp WHERE id_mp_from ='".$_SESSION['id']."' OR id_mp_to ='".$_SESSION['id']."'" (remplace le CASE par l'equivalent MySQL)
 
Ou alors avec un UNION entre une query qui fait WHERE id_mp_from = xxx et un autre qui fait WHERE id_mp_to = xxx. Le UNION devrai se débarasser des doublons.

Reply

Marsh Posté le 07-06-2011 à 10:11:51    

J'ai essayer et cela ne fonctionne pas :( escusez moi je suis un débutant et ce code me pose vraiment beaucoup de problème :(

Reply

Marsh Posté le 07-06-2011 à 10:23:59    

Tu as essayé quoi ?
Ça ne fonctionne pas ? Quel est le message d'erreur ou le résultat ?
 
http://forum.hardware.fr/hfr/Progr [...] 0261_1.htm

Reply

Marsh Posté le 07-06-2011 à 10:27:56    

Oui désolé je n'est pas été précis:)
 
Voici l'erreur  
 
Warning: mysql_fetch_assoc(): supplied argument is not a valid MySQL result resource in /mnt/154/sdb/7/6/delflorian/boite.php on line 83
 
A cette ligne 83 j'ai mon while de la requete vous m'aviez donné plus haut
 
:

Code :
  1. while ($auteurs = mysql_fetch_assoc($recherche_auteurs)){

Reply

Marsh Posté le 07-06-2011 à 11:19:56    

C'est une requete pour SQL Server, il faut la "traduire" pour que ca fonctionne avec MySQL (ce que je ne sais pas faire).

Reply

Marsh Posté le 07-06-2011 à 11:19:56   

Reply

Marsh Posté le 07-06-2011 à 11:28:31    

Cette erreur signifie que ta requête n'a pas aboutie, que $recherche_auteurs vaut false, et n'est donc pas un résultat mysql valide.

 

Dans ce cas, deux options pour trouver le problème :
- Ajouter ces lignes avant le while(mysql_fetch_assoc) :

Code :
  1. if (mysql_errno()) {
  2.  echo "MySQL error ".mysql_errno().": ".mysql_error()."\n<br>When executing:<br>\n$query\n<br>";
  3. }


- Soit, plus simplement, remplacer

Code :
  1. $recherche_auteurs = mysql_query("select distinct id_mp_from,id_mp_to from tbl_mp WHERE id_mp_from ='".$_SESSION['id']."' OR id_mp_to ='".$_SESSION['id']."'" );


par

Code :
  1. $sql = "select distinct id_mp_from,id_mp_to from tbl_mp WHERE id_mp_from ='".$_SESSION['id']."' OR id_mp_to ='".$_SESSION['id']."'";
  2. echo $sql; // ligne à ajouter ou supprimer suivant si tu débugges ou pas
  3. $recherche_auteurs = mysql_query($sql);


Message édité par Paulp le 07-06-2011 à 11:30:14
Reply

Marsh Posté le 07-06-2011 à 13:16:28    

Voici l'erreur :  
 
Warning: mysql_fetch_assoc(): supplied argument is not a valid MySQL result resource in /mnt/154/sdb/7/6/delflorian/boite.php on line 87
 
J'ai ajouter les lignes que vous m'avez dites sans succès :(
 
Voici le code actuel avec modif :

Code :
  1. $sql =" SELECT DISTINCT id_correspondant FROM(
  2.      (SELECT id_mp_from AS id_correspondant FROM tbl_mp WHERE id_mp_to ='".$_SESSION['id']."')
  3.      UNION
  4.      (SELECT id_mp_to FROM tbl_mp WHERE id_mp_from ='".$_SESSION['id']."')
  5.     )";
  6. print('<table border="2" align="center"><tr><th>Date</th><th>Auteur</th></tr>');
  7.     if (mysql_errno()) {
  8.      echo "MySQL error ".mysql_errno().": ".mysql_error()."\n<br>When executing:<br>\n$query\n<br>";
  9.     }
  10. $recherche_auteurs = mysql_query($sql);
  11. echo $sql;
  12. while ($auteurs = mysql_fetch_assoc($recherche_auteurs)){
  13.  $recherche_auteur= mysql_query("select pseudo_user,id_user from tbl_user WHERE id_user = '".$auteurs['id_correspondant']."'" );
  14.  $auteur= mysql_fetch_array($recherche_auteur);
  15.  if(nouveau_mp($_SESSION['id'],$auteur['id_user']) != false ){
  16.   print('<tr><td>Nouveau méssage</td>');
  17.  }else{
  18.   print('<tr><td>Pas de nouveaux méssage</td>');
  19.  }
  20.  print('<td><a href="boite.php?id='.$auteur['id_user'].'">'.$auteur['pseudo_user'].'</a></td></tr>');
  21. }
  22. print('</table>');


 
Cela ne vient t'il pas de la requete SQL? car avec mon ancienne requete cela ne s'affichait pas comme je voulais mais je n'avais pas d'erreur ?

Reply

Marsh Posté le 07-06-2011 à 13:22:11    

Il faut mettre la partie d'affichage de l'erreur (if mysql_errno()){...}) après le mysql_query.
 
Sinon, ça doit afficher la requête SQL, maintenant ?
Si oui, tu n'as plus qu'à la copier dans phpmyadmin pour voir ce que ça donne ...

Reply

Marsh Posté le 07-06-2011 à 13:32:26    

A oui désolé ^^"

 

Voici ce que ca ma ajouter :

 

MySQL error 1248: Every derived table must have its own alias
When executing:

 

Et oui en effet ma requête est bien afficher a l'écran
Sur PHP my admin j'ai exactement la même erreur.

 

Voici l'affichage complet sur ma page :

 


MySQL error 1248: Every derived table must have its own alias
When executing:

 

SELECT DISTINCT id_correspondant FROM( (SELECT id_mp_from AS id_correspondant FROM tbl_mp WHERE id_mp_to ='1') UNION (SELECT id_mp_to FROM tbl_mp WHERE id_mp_from ='1') )
Warning: mysql_fetch_assoc(): supplied argument is not a valid MySQL result resource in /mnt/154/sdb/7/6/delflorian/boite.php on line 91


Message édité par inoxis91 le 07-06-2011 à 13:36:42
Reply

Marsh Posté le 07-06-2011 à 13:36:56    

SELECT DISTINCT id_correspondant FROM( (SELECT id_mp_from AS id_correspondant FROM tbl_mp WHERE id_mp_to ='1') AS T1 UNION (SELECT id_mp_to FROM tbl_mp WHERE id_mp_from ='1') AS T2 )
 
Le message d'erreur est explicite ...

Reply

Marsh Posté le 07-06-2011 à 13:43:52    

Je l'est traduit en Francais mais même avec la traduction...
Maintenant SQL me met cette erreur :
 
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AS T2 )'
 
J'ai vérifier  les parenthèses ... et je vois pas pourqu'oi le AS T2 pose problème :(
 
Excuse  moi Paulp je suis débutant je te remercie de m'aider .

Reply

Marsh Posté le 07-06-2011 à 14:29:34    

Oups

 

SELECT DISTINCT id_correspondant FROM(SELECT id_mp_from AS id_correspondant FROM tbl_mp WHERE id_mp_to ='1' UNION SELECT id_mp_to FROM tbl_mp WHERE id_mp_from ='1') alias;

 

En fait, il veut que la table dérivée (donc le select ... union select ...) ait un alias, ce que j'ai rajouté


Message édité par Paulp le 07-06-2011 à 14:30:06
Reply

Marsh Posté le 07-06-2011 à 14:42:52    

Super!!! sa fonctionne!!! J'ai un peut de mal à comprendre votre requête,
Mais je pense que avec la pratique ca vas finir par rentrer :)
 
Merci beaucoup

Reply

Marsh Posté le 07-06-2011 à 14:48:45    

Décomposons :
Mettons la requête A :

Code :
  1. SELECT id_mp_from AS id_correspondant FROM tbl_mp WHERE id_mp_to ='1'

On sélectionne les id_mp_from des messages destinés à l'utilisateur 1

 

La requête B est quasiment identique :

Code :
  1. SELECT id_mp_to FROM tbl_mp WHERE id_mp_from ='1'

On sélectionne les id_mp_to des messages envoyés par l'utilisateur 1

 

La requête C est l'union de A et B :

Code :
  1. SELECT id_mp_from AS id_correspondant FROM tbl_mp WHERE id_mp_to ='1' UNION SELECT id_mp_to FROM tbl_mp WHERE id_mp_from ='1'

Elle retourne donc la liste des ids des utilisateurs ayant envoyés un mp à l'utilisateur 1 ou reçu un mp de l'utilisateur 1

 

La requête finale est un select distinct sur C pour n'avoir chaque id qu'une seule fois.

Code :
  1. SELECT DISTINCT id_correspondant FROM(SELECT id_mp_from AS id_correspondant FROM tbl_mp WHERE id_mp_to ='1' UNION SELECT id_mp_to FROM tbl_mp WHERE id_mp_from ='1') alias;


Message édité par Paulp le 07-06-2011 à 14:49:18
Reply

Marsh Posté le 07-06-2011 à 15:35:20    

Ça vas beaucoup mieux avec des explications :P merci pour tout!

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed