IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

Jointure et problème de sélection avec le WHERE


Sujet :

Langage PHP

  1. #1
    Membre habitué
    Homme Profil pro
    Webmaster
    Inscrit en
    Juillet 2015
    Messages
    518
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Juillet 2015
    Messages : 518
    Points : 184
    Points
    184
    Par défaut Jointure et problème de sélection avec le WHERE
    Bonjour,

    J'ai une table qui comporte des messages, chaque enregistrements à un id expéditeur ainsi qu'un id destinataire.

    Dans la table il peut donc y avoir plusieurs messages qui comporte le même expéditeur et le même destinataire si par exemple le membre 1 envoie 3 messages au membre 2 alors il y aura :
    id_expediteur / id_destinataire
    1 / 2
    1 / 2
    1 / 2
    donc 3 messages.

    le problème c'est que je suis en train de faire une boite de réception avec la liste des correspondants mais actuellement ma requête affiche justement l'ensemble des messages! je veux que ma requête "regroupe" les même id destinataire et expéditeur et affiche le pseudo du correspondant via une jointure. Je ne sais pas si j'ai été précis dans mon histoire ?

    voici une image de mes enregistrements de ma table messages
    Nom : phpmyadmin.jpg
Affichages : 111
Taille : 98,0 Ko

    maintenant disons que je suis le membre avec l'id 1 (pseudo demo)
    la photo affiche actuellement :
    Nom : affichage.jpg
Affichages : 110
Taille : 15,3 Ko

    Alors que j'attends un affichage de seulement 2 lignes car dans la photo phpmyadmin le membre 1 parle avec seulement 2 membres et pas 5 ! voila mon problème. Pas évident pour l'expliquer, je vous remercie pour votre aide je pense qu'il faut modifier le where mais je ne sais pas comment :/

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    $user_id = $_SESSION['auth']->id;
     
    	$reponse = $pdo->prepare("SELECT
    	u.id id_correspondant,
    	u.username pseudo_correspondant,
    	m.id id_msg,
    	m.id_expediteur id_exp,
    	m.id_destinataire id_des,
    	m.date_envoi date_msg
    FROM users u
    INNER JOIN messages m
    ON m.id_expediteur = u.id
    WHERE m.id_expediteur = $user_id OR m.id_destinataire = $user_id
    ORDER BY m.date_envoi DESC
    LIMIT 0, 20");

  2. #2
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    Ne met pas le detail des messages dans la requête puisque tu veux seulement les expediteurs/destinataires.
    Il n'y a pas besoin d'une requête préparée puisque tu n'as pas de paramètres.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    $reponse = $pdo->query("SELECT
    	DISTINCT u.id id_correspondant,
    	u.username pseudo_correspondant
    FROM users u
    INNER JOIN messages m ON m.id_expediteur = u.id
    WHERE m.id_expediteur = $user_id OR m.id_destinataire = $user_id
    ORDER BY m.date_envoi DESC
    LIMIT 0, 20");
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  3. #3
    Membre habitué
    Homme Profil pro
    Webmaster
    Inscrit en
    Juillet 2015
    Messages
    518
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Juillet 2015
    Messages : 518
    Points : 184
    Points
    184
    Par défaut
    ah je ne connaissais pas le SELECT DISTINCT

    merci infiniment

    sinon, je t’embête encore

    Si je suis le membre demo (id 1) je voudrais que la requête affiche le pseudo de mon interlocuteur et non le mien, actuellement dans la deuxieme ligne la requete affiche "demo" alors que demo c'est moi

    _________
    Boîte de réception
    Pseudo : test (Consulter la conversation)
    Pseudo : demo (Consulter la conversation)
    _________

    Il faudrait que la requête affiche le pseudo "encoreuntest" c'est le pseudo du membre qui porte l'id 3..

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    <?php
     
    // Connexion à la base de données
    require_once 'inc/db.php';
    $user_id = $_SESSION['auth']->id;
     
    $reponse = $pdo->query("SELECT DISTINCT
    	u.id id_correspondant,
    	u.username pseudo_correspondant
    FROM users u
    INNER JOIN messages m ON m.id_expediteur = u.id
    WHERE m.id_expediteur = $user_id OR m.id_destinataire = $user_id
    ORDER BY m.date_envoi DESC
    LIMIT 0, 20");
     
    while ($donnees = $reponse->fetch())
    {
    ?>
     
    Pseudo : <?php echo htmlspecialchars($donnees->pseudo_correspondant); ?> <a href="messages.php?idmbr=<?php echo $donnees->id_correspondant ?>">(Consulter la conversation)</a>
    <br>
     
    <?php
    }
    $reponse->closeCursor();
     
    ?>

  4. #4
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    Une possibilité :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT DISTINCT
    	IF (m.id_expediteur = $user_id, m.id_destinataire, m.id_expediteur) id,
            IF (m.id_expediteur = $user_id, u2.username, u1.username) pseudo
    FROM messages m
    JOIN users u1 ON m.id_expediteur = u1.id
    JOIN users u2 ON m.id_destinataire = u2.id
    WHERE m.id_expediteur = $user_id OR m.id_destinataire = $user_id
    ORDER BY m.date_envoi DESC
    LIMIT 0, 20
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  5. #5
    Membre habitué
    Homme Profil pro
    Webmaster
    Inscrit en
    Juillet 2015
    Messages
    518
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Juillet 2015
    Messages : 518
    Points : 184
    Points
    184
    Par défaut
    Ton code fonctionne parfaitement bien (sujet résolu grâce à toi) ! Je te remercie et je vais essayer de le décortiquer pour mon apprentissage

    sinon dans ton message tu dis "une possibilité" ?

  6. #6
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    A un moment j'avai pensé faire une union plutôt qu'une jointure et des conditions ... je ne sais pas lequel est le plus efficace, il faudrait mesurer.
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    SELECT DISTINCT id, username, date_envoi
    FROM (
             SELECT u1.id, u1.username, m1.date_envoi
             FROM messages m1 JOIN users u1 ON m1.id_expediteur = u1.id
             WHERE m1.id_destinataire = $user_id 
     
             UNION
     
             SELECT u2.id, u2.username, m2.date_envoi
             FROM messages m2 JOIN users u2 ON m2.id_destinataire = u2.id
             WHERE m2.id_expediteur = $user_id 
    )
    ORDER BY date_envoi DESC
    LIMIT 0, 20
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  7. #7
    Membre habitué
    Homme Profil pro
    Webmaster
    Inscrit en
    Juillet 2015
    Messages
    518
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Juillet 2015
    Messages : 518
    Points : 184
    Points
    184
    Par défaut
    oui je vois.. en tout cas j'ai essayé ton deuxième code mais il ne fonctionne pas (j'ai copié l'erreur ci-dessous) donc je garde le premier..

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    $reponse = $pdo->query("SELECT DISTINCT
    	IF (m.id_expediteur = $user_id, m.id_destinataire, m.id_expediteur) id,
    	IF (m.id_expediteur = $user_id, u2.username, u1.username) pseudo
    	FROM messages m
    	JOIN users u1 ON m.id_expediteur = u1.id
    	JOIN users u2 ON m.id_destinataire = u2.id
    	WHERE m.id_expediteur = $user_id OR m.id_destinataire = $user_id
    	ORDER BY m.date_envoi DESC
    	LIMIT 0, 20");
     
     
    $reponse = $pdo->query("SELECT DISTINCT id, username, date_envoi
    FROM (
    	SELECT u1.id, u1.username, m1.date_envoi
    	FROM messages m1 JOIN users u1 ON m1.id_expediteur = u1.id
    	WHERE m1.id_destinataire = $user_id
     
    	UNION
     
    	SELECT u2.id, u2.username, m2.date_envoi
    	FROM messages m2 JOIN users u2 ON m2.id_destinataire = u2.id
    	WHERE m2.id_expediteur = $user_id
    	)
    ORDER BY date_envoi DESC
    LIMIT 0, 20");
    erreur du deuxième code pour infos :
    ( ! ) Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 1248 Every derived table must have its own alias' in C:\wamp\www\pag\liste_messages.php on line 37
    ( ! ) PDOException: SQLSTATE[42000]: Syntax error or access violation: 1248 Every derived table must have its own alias in C:\wamp\www\pag\liste_messages.php on line 37
    ps : ligne 37 c'est : LIMIT 0, 20"); donc bizarre

    et aussi pour info mon code d'affichage :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    while ($donnees = $reponse->fetch())
    {
    ?>
     
    <?php echo htmlspecialchars($donnees->pseudo); ?>
    <a href="profils.php?idmbr=<?php echo $donnees->id ?>">Profil</a>
    <a href="messages.php?idmbr=<?php echo $donnees->id ?>">Consulter la conversation</a>
     
    <?php
    }
    $reponse->closeCursor();
     
    ?>

  8. #8
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    Comme indiqué dans l'erreur, il faut seulement mettre un alias.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     ) u
    ORDER BY date_envoi DESC
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  9. #9
    Membre habitué
    Homme Profil pro
    Webmaster
    Inscrit en
    Juillet 2015
    Messages
    518
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Juillet 2015
    Messages : 518
    Points : 184
    Points
    184
    Par défaut
    ok mais du coup dans le deuxième code il y a m1.date_envoi et m2.date_envoi je met quoi, je ne comprends pas trop le deuxième code

    visuellement le premier code à l'air moins "lourd" que le deuxième.. mais bon après il faut mesurer oui, je ne sais pas du tout comment mesurer un code

  10. #10
    Membre habitué
    Homme Profil pro
    Webmaster
    Inscrit en
    Juillet 2015
    Messages
    518
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Juillet 2015
    Messages : 518
    Points : 184
    Points
    184
    Par défaut
    Re sabotage,

    J'ai rajouté "date_lecture" après les deux IF et maintenant j'ai des doublons, pourquoi ? des conversations qui s'affichent en double dans la liste des conversation.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    <div class="table-responsive">
    	<table class="table table-striped table-hover">
     
    <?php
     
    // Connexion à la base de données
    require_once 'inc/db.php';
    $user_id = $_SESSION['auth']->id;
     
    $reponse = $pdo->query("SELECT DISTINCT
    	IF (m.id_expediteur = $user_id, m.id_destinataire, m.id_expediteur) id,
    	IF (m.id_expediteur = $user_id, u2.username, u1.username) pseudo,
    	date_lecture
    	FROM messages m
    	JOIN users u1 ON m.id_expediteur = u1.id
    	JOIN users u2 ON m.id_destinataire = u2.id
    	WHERE m.id_expediteur = $user_id OR m.id_destinataire = $user_id
    	ORDER BY date_envoi DESC
    	LIMIT 0, 30");
     
    while ($donnees = $reponse->fetch())
    {
    	switch ($donnees->date_lecture)
    	{
    		case null : $lecture_msg = "msg non lu dans cette conversation"; break;
    		case !null : $lecture_msg = "lu"; break;
    	}
    ?>
    		<tr>
    			<th><?php echo htmlspecialchars($donnees->pseudo); ?></th>
    			<th><?php echo "$lecture_msg" ?></th>
    			<th><a href="profils.php?idmbr=<?php echo $donnees->id ?>">Profil</a> - <a href="messages.php?idmbr=<?php echo $donnees->id ?>">Consulter la conversation</a></th>
    		</tr>
     
    <?php
    }
    $reponse->closeCursor();
     
    ?>
     
    	</table>
    </div>
    Nom : boite de recep.jpg
Affichages : 106
Taille : 75,5 Ko



    sans le "date_lecture" après les deux IF, aucun problème! mais dès que je rajoute le date_lecture j'ai des doublons.

  11. #11
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    S'il y a plusieurs messages, il y a plusieurs dates de lecture, tu te retrouves donc avec plusieurs lignes.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  12. #12
    Membre habitué
    Homme Profil pro
    Webmaster
    Inscrit en
    Juillet 2015
    Messages
    518
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Juillet 2015
    Messages : 518
    Points : 184
    Points
    184
    Par défaut
    ok je vois.. mais si je veux avoir un seul affichage (une ligne par conversation) il faut que je procède de quelle façon ?

    je veux que les "non lu dans cette conversation" et "lu" à coté de chaque conversations soit basé sur id_expediteur = $_GET['idmbr'] and id_destinataire = $user_id

    mais de quelle façon dois-je l'écrire ?

  13. #13
    Membre habitué
    Homme Profil pro
    Webmaster
    Inscrit en
    Juillet 2015
    Messages
    518
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Juillet 2015
    Messages : 518
    Points : 184
    Points
    184
    Par défaut
    trop compliqué le SELECT DISTINCT avec des IF j'y comprends rien! et pas faute de lire les docs avez-vous des docs à me conseiller sur le SELECT DISTINCT ou le UNION ?

    comment rajouter date_lecture dans le select sans avoir de doublons comme sur la photo ci dessus svp

    date_lecture basé sur la condition de : id_expediteur = $_GET['idmbr'] AND id_destinataire = $user_id

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <?php
    $reponse = $pdo->query("SELECT DISTINCT
    	IF (m.id_expediteur = $user_id, m.id_destinataire, m.id_expediteur) id,
    	IF (m.id_expediteur = $user_id, u2.username, u1.username) pseudo,
    	date_lecture
    	FROM messages m
    	JOIN users u1 ON m.id_expediteur = u1.id
    	JOIN users u2 ON m.id_destinataire = u2.id
    	WHERE m.id_expediteur = $user_id OR m.id_destinataire = $user_id
    	ORDER BY date_envoi DESC
    	LIMIT 0, 30");
    ?>
    je vous remercie pour votre aide

  14. #14
    Membre habitué
    Homme Profil pro
    Webmaster
    Inscrit en
    Juillet 2015
    Messages
    518
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Juillet 2015
    Messages : 518
    Points : 184
    Points
    184
    Par défaut
    j'ai essayé de rajouter : m.date_lecture à la fin du premier IF mais j'ai une erreur, fonctionne pas!
    je dois refaire un troisième IF sabotage ? pour éviter les doublons lors de la lecture d'un message. (cf photo ci dessus).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <?php
    	$reponse = $pdo->query("SELECT DISTINCT
    	IF (m.id_expediteur = $user_id, m.id_destinataire, m.id_expediteur, m.date_lecture) id,
    	IF (m.id_expediteur = $user_id, u2.username, u1.username) pseudo
    	FROM messages m
    	JOIN users u1 ON m.id_expediteur = u1.id
    	JOIN users u2 ON m.id_destinataire = u2.id
    	WHERE m.id_expediteur = $user_id OR m.id_destinataire = $user_id
    	ORDER BY date_envoi DESC
    	LIMIT 0, 30");
    ?>

  15. #15
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    La vraie question est de savoir quelle date_lecture tu veux puisqu'il y en une pour chaque message entre les deux utilisateurs.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  16. #16
    Membre habitué
    Homme Profil pro
    Webmaster
    Inscrit en
    Juillet 2015
    Messages
    518
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Juillet 2015
    Messages : 518
    Points : 184
    Points
    184
    Par défaut
    Si de id_desninataire=$id_user à id_expediteur=$id_expediteur il y a une (ou même plusieurs) date non lu (=null) alors je veux pouvoir l'afficher et dire que dans cette conversation vous avez un message non lu.
    Au fait, si tu veux c'est juste pour afficher un petit pictogramme à côté de chaque conversation dans la boîte de réception pour que l'utilisateur sache en un coup œil si il a des messages non lu dans cette conversation.

  17. #17
    Membre habitué
    Homme Profil pro
    Webmaster
    Inscrit en
    Juillet 2015
    Messages
    518
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Juillet 2015
    Messages : 518
    Points : 184
    Points
    184
    Par défaut
    j'ai encore essayé quelque chose mais raté !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    WHERE (m.id_expediteur = $user_id OR m.id_destinataire = $user_id) AND (m.date_lecture IS NULL OR m.date_lecture IS NOT NULL)
    j'ai toujours des doublons !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème requête sélection avec SQLite
    Par janyoura dans le forum Android
    Réponses: 8
    Dernier message: 12/12/2012, 23h04
  2. [XQUERY] Problème sum éléments avec clause where
    Par OLman135 dans le forum XQUERY/SGBD
    Réponses: 2
    Dernier message: 21/05/2012, 11h17
  3. [HQL] probléme requete HQL avec clause where in
    Par titawine dans le forum Hibernate
    Réponses: 3
    Dernier message: 16/05/2012, 10h02
  4. problème de sélection avec les champs vides
    Par danathane dans le forum Langage SQL
    Réponses: 2
    Dernier message: 23/08/2007, 16h45
  5. Problème de sélection avec LIKE
    Par Mr. Smith dans le forum Requêtes
    Réponses: 4
    Dernier message: 20/08/2006, 19h37

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo