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 SQL Discussion :

Requête SQL - système de commentaires


Sujet :

Langage SQL

  1. #1
    Nouveau membre du Club
    Inscrit en
    Février 2006
    Messages
    58
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 58
    Points : 34
    Points
    34
    Par défaut Requête SQL - système de commentaires
    Bonjour,

    J'aimerais réaliser un système de commentaire comme sur Couchsurfing.org, c'est-à-dire que deux personnes peuvent écrire chacun sur le profil de l'autre et le système affiche sur chaque profil les commentaires des deux personnes.



    Voici ma table des commentaires:

    - id
    - sender (int)
    - target (int)
    - opinion
    - commentaire
    - date

    Sender et target sont les id des membres qui s'envoient des messages.

    Quand on va sur le profil d'une "target" on affiche tous les commentaires envoyés par les "sender".

    Comment arrangeriez-vous la requête SQL? J'aimerais récupérer les données en une fois.

    Pour l'instant c'est celle-ci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $sql = 'SELECT c.opinion,c.commentaire,c.date,user.login 
    	FROM commentaires AS c 
    	LEFT JOIN user ON user.id=c.sender
    	WHERE target=:target 
    	ORDER BY date DESC';

    Merci beaucoup

  2. #2
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Qu'est-ce qui ne va pas avec ta requête ?
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  3. #3
    Nouveau membre du Club
    Inscrit en
    Février 2006
    Messages
    58
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 58
    Points : 34
    Points
    34
    Par défaut
    Ma requête fonctionne mais elle ne liste que les messages s'adressant au membre X dont on visite le profil.

    Ce que je voudrais c'est que quand le membre X envoie un commentaire sur le profil d'un membre Y, ce commentaire apparaisse également sur le profil de X juste en-dessous du message de Y dès que ce dernier aura commenté à son tour le profil de X.

    C'est un système de confiance. Sur couchsurfing, quand on a été hébergé par un membre du site on dépose un commentaire disant ce qu'on pense de cette personne. Comme ça les autres gens peuvent voir si c'est une personne de confiance. Si je poste des insultes sur le profil d'un autre membre il faut que ce message apparaissent aussi sur mon propre profil. De cette façon les gens voient que je suis une personne grossière et cela incite chacun à être respectueux lors de l'envoi de commentaires.

    J'aimerais implémenter le même principe même si mon projet ne traite pas du même sujet que couchsurfing.org

    Comment modifieriez-vous la requête SQL?

    Merci!

  4. #4
    Membre du Club
    Inscrit en
    Juin 2007
    Messages
    158
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 158
    Points : 64
    Points
    64
    Par défaut
    Bonjour,

    Si j'ai bien comprit votre besoin

    la requête suivante peut faire l'affaire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    select * from(
     
    SELECT c.opinion,c.commentaire,c.date,user.login 
    	FROM commentaires AS c ,user 
    	where user.id=c.sender
    	and target=target 
    union 
    SELECT c.opinion,c.commentaire,c.date,user.login 
    	FROM commentaires AS c ,user 
    	where target=c.sender
    	and target=user
    )
    ORDER BY date DESC

    sachant que user c'est l'utilisateur courant (sur son profil)

    J'espère que ça peut vous aider!

  5. #5
    Nouveau membre du Club
    Inscrit en
    Février 2006
    Messages
    58
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 58
    Points : 34
    Points
    34
    Par défaut
    Merci pour votre aide mar1985 mais en testant votre requête j'obtiens l'erreur suivante:

    #1248 - Every derived table must have its own alias
    J'ai cherché sur Google mais je n'arrive pas à trouver une solution

    Que se passe-t-il?

    Merci

  6. #6
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Le message signifie qu'il faut mettre un alias après la parenthèse fermante dans la requête, par exemple tmp puisque c'est en quelque sorte une table temporaire.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  7. #7
    Nouveau membre du Club
    Inscrit en
    Février 2006
    Messages
    58
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 58
    Points : 34
    Points
    34
    Par défaut
    Merci,

    Voici la table des commentaires:



    La requête SQL:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    SELECT * FROM(								
    SELECT c.id,c.opinion,c.commentaire,c.date,user.login 									
    FROM commentaires AS c ,user 									
    WHERE user.id=c.sender									
    AND target=57								
    union 								
    SELECT c.id,c.opinion,c.commentaire,c.date,user.login 									
    FROM commentaires AS c ,user 									
    WHERE target=c.sender									
    AND target=57							
    ) AS tmp							
    ORDER BY id ASC
    Le résultat obtenu:


    Je n'ai qu'un résultat alors qu'il faudrait afficher deux messages. Ce que je voudrais, c'est que en consultant le profil de Jean (son id=57) je voie:
    1) le message de Seb (disant ce qu'il pense de Jean)
    2) ensuite le message que Jean à posté sur le profil de Seb

    Merci pour votre aide!

  8. #8
    Nouveau membre du Club
    Inscrit en
    Février 2006
    Messages
    58
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 58
    Points : 34
    Points
    34
    Par défaut
    Bonjour,

    Comme je n'arrive pas au résultat attendu et afin de mieux me faire comprendre j'ai programmé ce que j'aimerais obtenir via une seule requête SQL . L'exemple ci-dessous implique deux boucles while imbriquées ce qui n'est pas joli et fonctionnel. Pouvez-vous m'aider? Merci beaucoup!

    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
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
     
    $target = (int)$_GET['id']; 
    //Tous les commentaires postés sur le profil de Jean
     
    $sql = 'SELECT c.opinion,c.commentaire,c.date,c.sender,user.login 
    	  FROM comment_profile AS c 
    	  LEFT JOIN user ON user.id=c.sender
    	  WHERE target=:target 
    	  ORDER BY date DESC';
     
    $req = $dbh->prepare($sql);          
    $valeurs = array(':target'=>$target);
     
    $req->execute($valeurs);
    while($data = $req->fetch(PDO::FETCH_OBJ)):?>
    	<div class="com">
    		<span class="auteur"><a href="profile.php?id=<?php echo $data->sender; ?>"><?php echo $data->login;?></a></span>
    		<span class="opinion">
    			<?php 
    			$opinion = $data->opinion;
    			if($opinion==3) $opinion = "Positif";
    			elseif($opinion==2) $opinion = "Neutre";
    			elseif($opinion==1) $opinion = "Négatif";
    			echo $opinion;
    			?>
    		</span>
    <p><?php echo htmlentities($data->commentaire,ENT_QUOTES,'UTF-8');?></p>
    <span class="date"><?php echo $data->date;?></span>
    <?php
    //Si Marc écrit un commentaire C sur le profil de Jean, il faut que les //commentaires de Jean sur le profil de Marc apparaissent également sur son //propre profil sous le commentaire C.
     
    $myTarget = $data->sender;
     
    $sql = 'SELECT c.opinion,c.commentaire,c.date,c.sender,user.login 
    	  FROM comment_profile AS c 
    	  LEFT JOIN user ON user.id=c.sender
    	  WHERE target=:target AND sender=:sender 
    	 ORDER BY date DESC';
    $req = $dbh->prepare($sql);             
    $valeurs = array(':target'=>$myTarget,
    		      ':sender'=>$target);   
    //$target est Jean:   tous les messages que Jean à envoyé sur le profil de Marc
     
    //on affiche ces messages sur le profil de Jean (en-dessous du commentaire de Marc)
    while($data_trust = $req->fetch(PDO::FETCH_OBJ)):?>
    <span class="auteur"><a href="profile.php?id=<?php echo $data_trust->sender; ?>"><?php echo $data_trust->login;?></a></span>
     
    <span class="opinion">
    	<?php 
    		$opinion = $data_trust->opinion;
    		if($opinion==3) $opinion = "Positif";
    		elseif($opinion==2) $opinion = "Neutre";
    		elseif($opinion==1) $opinion = "Négatif";
    		echo $opinion;
    	?>
    </span>
    <p><?php echo htmlentities($data_trust->commentaire,ENT_QUOTES,'UTF-8');?></p>
    <span class="date"><?php echo $data_trust->date;?></span>
    <?php endwhile;?>	
    </div>
     
    <?php endwhile;?>

  9. #9
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Je crois qu'une petite erreur s'est glissée dans la seconde sous-requête de ta requête union :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    WHERE target=c.sender									
    AND target=57
    Cette condition ne restreint-elle pas aux messages envoyés par le user 57 à lui-même ?

    Et puis les jointures s'écrivent depuis 20 ans avec l'opérateur JOIN ; il serait temps de s'y mettre !

    Essaie cette requête :
    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
    SELECT *
    FROM
    (
    	-- Commentaires envoyés par le user 57
    	SELECT c.id, c.opinion, c.commentaire, c.date, -- date est un mot réservé du SQL, mauvais nom de colonne !
    		u.login
    	FROM commentaires AS c
    	INNER JOIN user AS u ON u.id = c.sender
    	WHERE c.sender = 57
    	UNION
    	-- Commentaires reçus par le user 57
    	SELECT c.id, c.opinion, c.commentaire, c.date, -- date est un mot réservé du SQL, mauvais nom de colonne !
    		u.login
    	FROM commentaires AS c
    	INNER JOIN user AS u ON u.id = c.target
    	WHERE c.target = 57
    ) AS tmp
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  10. #10
    Nouveau membre du Club
    Inscrit en
    Février 2006
    Messages
    58
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 58
    Points : 34
    Points
    34
    Par défaut
    Merci beaucoup CinePhil! Ca marche presque parfaitement après avoir adapté un tout petit peu la requête. Merci aussi pour la note sur le champ "date" que je vais changer.

    J'ai néanmoins un problème d'affichage. Sur l'image vous pouvez voir que le membre "tv" poste un commentaire sur le profil de Seb, ce dernier lui répondant mais il y a le membre "lion" qui s'incruste entre tv et Seb... comment classer les commentaires par un ORDER BY approprié?

    Aussi, j'aimerais que l'affichage soit décroissant DESC c'est-à-dire que les expériences les plus récentes seraient en haut de page. Mais on doit trier par "expérience entre deux personnes" et pas par date car les gens peuvent envoyer leurs commentaires quand ils le veulent. L'idée c'est qu'un membre ne soit pas pénalisé pour toujours (en affichant un mauvais commentaire en haut de page) si sa première expérience sur le site ne s'est pas bien passée.

    Encore merci pour ton aide précieuse!



    Voici la requête:
    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
     
    SELECT *
    FROM
    (
    -- Commentaires reçus par le user 44
    	SELECT c.id, c.sender,c.opinion, c.commentaire, c.date, 
    	       u.login
    	FROM comment_profile AS c
    	INNER JOIN user AS u ON u.id = c.sender
    	WHERE c.target = 44
            UNION
    -- Commentaires envoyés par le user 44
            SELECT c.id,c.sender, c.opinion, c.commentaire, c.date,
    	       u.login
    	FROM comment_profile AS c
    	INNER JOIN user AS u ON u.id = c.sender
    	WHERE c.sender = 44
     
    ) AS tmp
    Et son résultat:


Discussions similaires

  1. [Système forums] Aide sur une requête SQL
    Par crazy_inf dans le forum Requêtes
    Réponses: 4
    Dernier message: 04/12/2011, 18h27
  2. [ DB2 ] [ AS400] requête sql
    Par zinaif dans le forum DB2
    Réponses: 6
    Dernier message: 23/08/2008, 19h42
  3. [Système] Log des requêtes SQL
    Par eric41 dans le forum Langage
    Réponses: 6
    Dernier message: 13/08/2007, 09h31
  4. Utilisation de MAX dans une requête SQL
    Par Evil onE dans le forum Langage SQL
    Réponses: 7
    Dernier message: 15/06/2004, 18h38
  5. Requête SQL
    Par Leludo dans le forum Langage SQL
    Réponses: 2
    Dernier message: 17/02/2003, 16h44

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