Problème avec requête SQL multiple (3 tables) et comptage

WRInaute passionné
Bonjour,

Je suis actuellement en train d'écrire un petit code afin d'afficher des rêves sur mon site qui leur est dédié : -http://www.boiteareves.com (je remercie d'ailleurs une nouvelle fois Pipologue pour le site :) ).

Les premiers mots des rêves sont d'abord affichés les uns en dessous des autres, des liens menant ensuite sur les pages d'affichage individuel des rêves.

Je bloque actuelllement sur l'affichage du nombres de réponses (appelées pour le moment "interprétations") à chaque rêve sur ces pages de navigation affichant plusieurs rêves.

Données :
La chose est sur un 60gp d'ovh.
Table "reves_reves" : les textes des rêves y sont stockés avec leur n° d'id.
Table "reves_reveurs" : les membres du site y sont enregistrés avec leurs informations (notamment leur pseudo). Chaque rêveur a un id.
Table "reves_interpretations" : les "réponses" aux rêves. Chaque réponse a son propre id et un champ "id_reve" indiquant le n° d'id du rêve correspondant.

Je travaille actuellement sur le code suivant :

Code:
// Sélection des rêves online
$sql = "SELECT
        RR.id, RR.pseudo_id, RR.pseudo,
        RR.email, RR.email_publication, RR.titre,
        RR.reve, RR.date,
        RRVR.pseudo as pseudo_inscrit
FROM
        reves_reves RR, reves_interpretations RI

INNER JOIN reves_reveurs RRVR
ON RRVR.id = RR.pseudo_id

WHERE
        RR.activity='on'
GROUP BY
         RR.id
ORDER BY
         RR.id DESC
LIMIT
         $reves_bckid,$nb_reves_aff";

$req = mysql_query($sql) or die(mysql_error());

// Affichage des rêves
while($db_data_reves = mysql_fetch_assoc($req)) {
trululuuu...
}

Si le rêveur est membre alors quand il envoit son rêve, son pseudo n'est pas stocké dans la table reves_reves.
Si le rêveur est membre, alors il a un id supérieur à 0, et le code affichera son "pseudo_inscrit" (code du while{}), sinon il affichera son pseudo donné lors de l'envoi du rêve (pris dans le champ pseudo de la table reves_reves).

Partant de là, je ne vois pas du tout comment obtenir facilement et efficacement le nombre d'interprétations (cad le nombre d'enregistrements de la table reves_interpretations dont le champ id_reve est égal à l'id du rêve traité) pour ensuite l'afficher.
Il ne me semble évidemment pas très recommandé de faire une requête SQL à chaque tour de boucle ;-).
J'ai un peu tout essayé mais sans succès aucun (à noter que s'il y a plus efficace pour le reste aussi, je prends également bien sûr ;-) ). J'y suis depuis un bon moment et je ne trouve rien de probant :?.

Comment faire svp ?
Je ne sais pas ce que je donnerais pour avoir la solution miracle là !
 
WRInaute discret
Bonjour;
Si la variable retournée est un associatif, tu dois pouvoir tester par une variable tampon la valeur de l'id du rêve, présente sur chaque ligne et tester alors la diff entre l'id du rêve courant et celle de la variable tampon à réaffecter à chaque tour dans le while et du coup commande rl'affichage ou pas.
En gros, quand l'id du rêve change, tu l'affiches ($idreve!=$reve_tampon) et pour le reste tu affiches les interprétations correspondantes.
 
WRInaute passionné
kasar a dit:
Bonjour;
Si la variable retournée est un associatif, tu dois pouvoir tester par une variable tampon la valeur de l'id du rêve, présente sur chaque ligne et tester alors la diff entre l'id du rêve courant et celle de la variable tampon à réaffecter à chaque tour dans le while et du coup commande rl'affichage ou pas.
En gros, quand l'id du rêve change, tu l'affiches ($idreve!=$reve_tampon) et pour le reste tu affiches les interprétations correspondantes.

Je ne comprends pas du tout ce que tu dis :-/.

Mais je ne veux pas afficher les interprétations correspondantes mais simplement les compter et afficher leur nombre.
 
WRInaute accro
Je veux bien essayer de t'aider mais à vrai dire je n'y comprends pas grand chose. Les informations sont éparpillées...

Peut tu faire un mini shéma ou être plus explicite stp.
 
WRInaute passionné
Merci de ta réponse thierry8 :). Je vais essayer de reprendre tout ça plus clairement alors :). C'est parti ^^ :

I°) Contexte :
La Boîte à rêves est un site sur lequel les visiteurs peuvent déposer et lire leurs rêves. Ils peuvent également proposer des interprétations possibles des rêves.

A°) Rêves :
Les rêves sont stockés dans une table "reves_reves". Voici sa structure :

Code:
reves_reves` (
  `id` int(10) unsigned NOT NULL auto_increment, --> id du rêve.
  `pseudo_id` int(10) NOT NULL default '0', --> n° de pseudo du rêveur si et seulement si ce rêveur est un membre (une zone membres allant ouvrir ultérieurement).
  `pseudo` varchar(50) NOT NULL default '', --> pseudo du rêveur si et seulement si ce rêveur n'est pas un membre (s'il est membre ce champ reste vide).
  `email` varchar(50) NOT NULL default '', --> email du rêveur si et seulement si ce rêveur n'est pas un membre (s'il est membre ce champ reste vide).
  `email_publication` varchar(50) NOT NULL default '', --> état de publication publique de l'email du rêveur si et seulement si ce rêveur n'est pas un membre (s'il est membre ce champ reste vide).
  `titre` varchar(100) NOT NULL default '', --> titre du rêve.
  `reve` text NOT NULL, --> texte du rêve.
  `date` datetime NOT NULL default '0000-00-00 00:00:00', --> date du rêve.
  `ip` varchar(15) NOT NULL default '', --> ip du rêveur.
  `activity` char(3) NOT NULL default '', --> activité du rêve. le rêve peut être soit "on"(line) soit "off"(line). Par défaut les nouveux rêves enregistrés sont offline. Je les valide ensuite après vérification et les passe en "on"(line).
  PRIMARY KEY  (`id`) --> ...
)

B°) Rêveurs :
Les rêveurs auront bientôt la possibilité de s'inscrire en tant que membres. Cela leur permettra entre autres de ne pas avoir à retaper leurs infos à chaque nouveau rêve envoyé. De plus si le rêveur enregistré change certaines de ses données affichées sur les pages d'affichage de ses rêves, celles-ci prennent en compte ces modifications. C'est la raison pour laquelle dans la table "reves_reves" certains champs (comme le pseudo par exemple) restent vides : les infos sont en effet prises directement dans la table reves_reveurs.
Voici la structure de la table "reves_reveurs" reprenant les principales données de celle-ci :

Code:
`reves_reveurs` (
  `id` int(10) NOT NULL auto_increment, --> id du rêveur (le champ id_pseudo de la table "reves_reveurs" reprend cet id, qui permet d'identifier ainsi l'auteur d'un rêve d'un membre).
  `pseudo` varchar(30) NOT NULL default '', --> pseudo du rêveur.
  `email` varchar(50) NOT NULL default '',
  `email_publication` char(3) NOT NULL default '',
  `nb_reves_aff` int(2) NOT NULL default '0',, --> nombre de rêves à afficher par page (option non déterminante dans mon problème).
  PRIMARY KEY  (`id`)
)

C°) Interprétations :
La table "reves_interpretations" contient les interprétations proposées par les visiteurs et rêveurs enregistrés. En voici la structure :

Code:
`reves_interpretations` (
  `id` int(5) unsigned NOT NULL auto_increment, --> id de l'interprétation.
  `id_reve` int(5) unsigned NOT NULL default '0', --> id du rêve interprété (correpond donc au champ "id" de la table "reves_reves".
  `pseudo_id` int(10) NOT NULL default '0', --> id du pseudo si le rêveur est membre.
  `pseudo` varchar(50) NOT NULL default '', --> pseudo du rêveur s'il n'est pas membre.
  `email` varchar(50) NOT NULL default '', --> email du rêveur s'il n'est pas membre.
  `email_publication` varchar(50) NOT NULL default '', --> état de publication de l'email du rêveur s'il n'est pas membre.
  `interpretation` text NOT NULL, --> texte de l'interprétation proposée.
  `date` datetime NOT NULL default '0000-00-00 00:00:00', --> date de l'interprétation.
  `ip` varchar(15) NOT NULL default '', --> id du posteur de l'interprétation.
  `activity` varchar(5) NOT NULL default '', --> même système que pour les rêves, sauf que les interprétations sont publiées directement par défaut (le champ a donc la valeur "on" par défaut").
  PRIMARY KEY  (`id`)
)


II°) Objectif

A°) Définition de l'objectif
Le but de la maneuvre est d'afficher les 10 premiers rêves. Avec :
- titre/date/texte du rêve (pas trop dur ça, ça va ;-) ).
- le nombre d'interprétations proposées pour le rêve.
- le pseudo du rêveur.

B°) Cas du pseudo du rêveur :

1°) Rêveur non-membre :
Si le rêveur n'est pas membre, alors le champ "id_pseudo" de la table "reves_reves" correspondant au rêve est égal à "0". On affichera alors les informations alors renseignées dans les champs "pseudo", "email",... (qui sont vides si le rêveur est membre).

2°) Rêveur membre :
Si le rêveur est membre alors le champ "id_pseudo" de la table "reves_reves" correspondant au rêve est égal à son id (supérieur à 0). On affichera alors les informations alors renseignées dans les champs de la table "reves_reveurs", là où le champ "id" (de la table "reves_reveurs") est égal à la valeur du champ "id_pseudo" de la table "reves_reves"...


Voilà donc le code que j'ai bidouillé :

Code:
// Sélection des rêves online
$sql = "SELECT
        RR.id, RR.pseudo_id, RR.pseudo,
        RR.email, RR.email_publication, RR.titre,
        RR.reve, RR.date,
        RRVR.pseudo as pseudo_inscrit
FROM
        reves_reves RR

INNER JOIN reves_reveurs RRVR
ON RRVR.id = RR.pseudo_id

WHERE
        RR.activity='on'
GROUP BY
         RR.id
ORDER BY
         RR.id DESC
LIMIT
         0,10";

$req = mysql_query($sql) or die(mysql_error());

// Affichage des rêves
while($db_data_reves = mysql_fetch_assoc($req)) {

   $id_reve = $db_data_reves['id'];
   
   // Affichage du rêve
   echo "<h2 id=\"r".$id_reve."\"><a href=\"reve.php?id=".$id_reve."&amp;titre=";
   titre_url($db_data_reves['titre']);
   echo "\">".$db_data_reves['titre']."</a></h2>
   <p class=\"reve_infos\">Le ";
   datetime_fr($db_data_reves['date']);
   
   // Si le rêveur est inscrit
   if ($db_data_reves['pseudo_id'] >= 1) {
      echo ", <a href=\"reveur-infos.php?pseudo_id=".$db_data_reves['pseudo_id']."\">".$db_data_reves['pseudo_inscrit']."</a>";
   }
   
   // Si le rêveur n'est pas inscrit
   else {
      if ($db_data_reves['email_publication'] == 'yes') {
         echo ", ".$db_data_reves['pseudo']." (<a href=\"mailto:".$db_data_reves['email']."\">@</a>)";
      }
      else {
         echo ", ".$db_data_reves['pseudo'];
      }
   }
   $reve = $db_data_reves['reve'];
   $max_caracteres = 350;
   if (strlen($reve)>$max_caracteres) {
	   $max_caracteres=strrpos(substr($reve, 0, $max_caracteres), " ");
	   $reve = substr($reve, 0, $max_caracteres);
	   $reve .= " (...)";
   }
	 
   echo " a confié le rêve suivant à la boîte à rêves :</p>
   <p class=\"reve\">$reve</p>";

   echo "<p class=\"right\">";
   if (strlen($reve)>$max_caracteres) {
   	   echo "<a href=\"reve.php?id=".$id_reve."&amp;titre=";
	   titre_url($db_data_reves['titre']);
	   echo "\">Lire la suite du rêve...</a> | ";
   }
   
   echo "<a href=\"reve.php?id=".$id_reve."&amp;titre=";
   titre_url($db_data_reves['titre']);
   echo "#add-interpretation\">Proposer une interprétation</a>
   | <a href=\"reve.php?id=".$id_reve."&amp;titre=";
   titre_url($db_data_reves['titre']);
   echo "#interpretations\">Lire les interpretations proposées</a>
   </p>
   
   <p>&nbsp;</p>";
   
}

Mais ce code n'affiche pas le nombre d'interprétations proposées pour chacun des rêves affichés.


Vouala. J'espère avoir été plus précis et concis par rapport à ma situation. En cas de doute, n'hésitez surtout pas à me posez des questions ou faire des suggestions sur la structuration des choses (si vous pensez à un système plus simple mais tout aussi efficace par exemple).
 
WRInaute accro
J'ai fait un petit tour vite fait, mais vu l'heure je prendrai un petit temps pour me pencher sur le problème plutôt demain.

Mais au niveau des tables déjà, ce n'est pas ça.. ;)

Sinon, lorsque tu parle d'interprétation, c'est un genre de réponse(s) au(x) rêve(s) ?
 
WRInaute accro
Code:
$sql = "
   SELECT COUNT(*) AS nb_reve_interpret
   FROM reves_interpretations r_i
   INNER JOIN reves_reves r_r
   ON r_i.id_reve = r_r.pseudo_id
   WHERE r_r.activity='on'
   GROUP BY r_r.id
   ORDER BY r_r.id DESC
   LIMIT 0,10;
   ";

Essaye voir cette requête.
Si ça ne fonctionne pas, dis moi ce qui cloche !
(désolé, mais le pb c'est que je ne peux tester du fait
que je n'ai pas les tables, donc il va falloir jongler)


Normalement tu devrais obtenir le nombre d'interprétation pour tes 10 premiers rêves. En espérant avoir bien compris.

Tiens moi au courant de la chose.

PS: Je ne pense pas que le GROUP BY soit nécessaire.
 
WRInaute passionné
Uiui, les interprétations sont des sortes de réponses aux rêves, c'est ça :).
Je veux afficher le nombre d'interprétations postées pour chaque rêve, à la manière de ce qu'on fait sur les pages de navigation des blogs (début du billet est écrit, avec le pseudo, l'heure et le nombre de commentaires postés / ici ce ne sont pas des commentaires mais des "interprétations").

Si je fais ça :

Code:
// Sélection des rêves online
$sql = "SELECT COUNT(*) AS nb_reve_interpret
   FROM reves_interpretations r_i
   INNER JOIN reves_reves r_r
   ON r_i.id_reve = r_r.pseudo_id
   WHERE r_r.activity='on'
   GROUP BY r_r.id
   ORDER BY r_r.id DESC
   LIMIT 0,10";

$req = mysql_query($sql) or die(mysql_error());

// Affichage des rêves
while($db_data_reves = mysql_fetch_assoc($req)) {
echo $db_data_reves['nb_reve_interpret'];
}

Cela m'affiche seulement "1". Et je ne sélectionne pas non plus le texte du rêve et le pseudo du rêveur :-/.
 
WRInaute accro
Je pense que dans tous les cas il te faudra 2 requêtes. (pseudo+texte & nb interprétations)

Est-il possible d'avoir en fichier sql (pour mysql) ces trois tables avec des données ?

Cela me permettrais de tester, et de voir le résultat...
parce que là j'avoue que c'est difficile de me faire une idée sur les résultats.

J'aimerais faire deux trois test, je ne pense pas que ce soit bien difficile.
Ca sera plus pratique.

Si tu est d'accord je t'envois mon e-mail par mp.
 
WRInaute accro
Arg ! Ma requête était juste je me suis trompé à un petit endroit !
( évident d'ailleurs ! tu aurais du le remarquer ! ;) )
ON r_i.id_reve = r_r.pseudo_id au lieu de ON r_i.id_reve = r_r.id

Code:
   SELECT COUNT(*) AS nb_reve_interpret, r_r.id
   FROM reves_interpretations r_i
   INNER JOIN reves_reves r_r
   ON r_i.id_reve = r_r.id
   WHERE r_r.activity='on'
   GROUP BY r_r.id
   ORDER BY r_r.id DESC
   LIMIT 0,10;

OU

Code:
   SELECT COUNT( * ) AS nb_reve_interpret, r_i.id
   FROM reves_interpretations r_i
   INNER JOIN reves_reves r_r 
   ON r_i.id_reve = r_r.id
   WHERE r_r.activity = 'on'
   GROUP BY r_i.id_reve
   ORDER BY r_i.id_reve DESC
   LIMIT 0 , 10;

Tu as le choix ! ;)
La première travail plus que sur la table reves_reves et la seconde principalement sur la table reves_interpretations

Le résultat sera identique.
En terme de performance/optimisation il faut choisir...

- la solution 1 si tu pense avoir plus de rêves que d'interprétations

- la solution 2 si tu pense avoir plus d'interprétations que de rêves

Pour chacune des deux requêtes j'ai laissé r_r.id après le SELECT COUNT( * ) AS nb_reve_interpret.
Cela te permettra de tester sous phpmyadmin et de voir le résultat trier par ordre croissant sur l'id
(donc sur les rêves) et à coté le nombre d'interprétation(s).

Voila ! Maintenant y a plus cas.... :wink:
 
WRInaute passionné
J'étais dans mon lit avec une gasto, donc pas encore eu le temps de tester, je suis vraiment désolé :(. Je commence à me remettre sur pieds et viens de tester ton code : ça marche presque parfaitement bien. En fait quand il n'y a aucune interprétation, le script saute ce rêve sans interprétation. Par exemple pour mes 10 derniers rêves :

Code:
// Sélection des rêves online
$sql = "SELECT COUNT(*) AS nb_reve_interpret, r_r.id
   FROM reves_interpretations r_i
   INNER JOIN reves_reves r_r
   ON r_i.id_reve = r_r.id
   WHERE r_r.activity='on'
   GROUP BY r_r.id
   ORDER BY r_r.id DESC
   LIMIT 0,10";

$req = mysql_query($sql) or die(mysql_error());

// Affichage des rêves
while($db_data_reves = mysql_fetch_assoc($req)) {
echo $db_data_reves['id']." : ".$db_data_reves['nb_reve_interpret']."<br />";
}

Cela m'affiche :

671 : 1
670 : 1
669 : 1
668 : 2
667 : 2
666 : 1
664 : 3

663 : 3
662 : 2
661 : 1

Alors qu'il existe un rêve 665, qui n'a aucune interprétation postée par contre.
Le but serait d'avoir la valeur "0" si il n'y a pas d'interprétation, afin de faire plus facilement ma boucle affichant les rêves + le nombre d'interprétations.
Mais je ne comprends pas bien pourquoi ça n'affiche pas au moins $db_data_reves['id'] (ici 665) :- ?
 
WRInaute accro
ok

Comme je t'avais vu plusieurs fois sur le forum,
je me posais la question.

Et bien bon rétablissement.
 
WRInaute accro
Je suis venu faire un tour et je viens de voir que tu avais laissé un message précédent le mien.
Désolé, je n'avais pas vu.
Je pense que c'est réglé à présent ?
 
WRInaute passionné
Non, je n'ai pas malheureusement pas encore trouvé l'astuce permettant de faire ce que je voulais :-(...
 
WRInaute accro
Ben, c'est simple...
SI aucun résusltat c'est forcément 0.

Donc tu compare l'id du rêve...
si pour l'id du rêve tu ne trouve aucun résultat tu affiche zéro.. :?
 
WRInaute passionné
Un truc comme ça :

Code:
// Sélection des rêves online
$sql = "SELECT COUNT(*) AS nb_reve_interpret, r_r.id
   FROM reves_interpretations r_i
   INNER JOIN reves_reves r_r
   ON r_i.id_reve = r_r.id
   WHERE r_r.activity='on'
   GROUP BY r_r.id
   ORDER BY r_r.id DESC
   LIMIT 0,10";

$req = mysql_query($sql) or die(mysql_error());

// Affichage des rêves
while($db_data_reves = mysql_fetch_assoc($req)) {
	if (isset($db_data_reves['nb_reve_interpret'])) {
		echo $db_data_reves['id']." : ".$db_data_reves['nb_reve_interpret']."<br />";
	}
	else {
		echo $db_data_reves['id']."0 interpretations";
	}
}

:? ?
 
WRInaute accro
Non car ton isset($db_data_reves['nb_reve_interpret']) sera toujours vrai.

D'abord tu met tout les résultats de ta requête (nb interp.) dans un tableau associatif (ou non).

Ensuite tu as ta première requête qui prend les rêves, dans dans cette boucle d'affichage des 10 premiers rêves, tu teste si l'id du rêve existe dans le tableau associatif, tu récupère le résultat, sinon 0. tu vois ?

Sinon donne le code ou tu affiche tes 10 premiers rêves. (requête + boucle)
 
WRInaute passionné
thierry8 a dit:
D'abord tu met tout les résultats de ta requête (nb interp.) dans un tableau associatif (ou non).

Je ne vois pas ça :oops: .

Sinon voilà mon code entier affichant actuellement les 10 derniers rêves :
Code:
// Si la personne est membre, on prend son nombre de rêves à afficher
if (!isset($_SESSION['nb_reves_aff'])) {
	$nb_reves_aff = '10';
}
else {
	$nb_reves_aff = $_SESSION['login_nb_reves_aff'];
}

$reves_bckid = $p*$nb_reves_aff;

// Sélection des rêves online
$sql = "SELECT
        RR.id, RR.pseudo_id, RR.pseudo,
        RR.email, RR.email_publication, RR.titre,
        RR.reve, RR.date,
        RRVR.pseudo as pseudo_inscrit
FROM
        reves_reves RR

INNER JOIN reves_reveurs RRVR
ON RRVR.id = RR.pseudo_id

WHERE
        RR.activity='on'
GROUP BY
         RR.id
ORDER BY
         RR.id DESC
LIMIT
         $reves_bckid,$nb_reves_aff";

$req = mysql_query($sql) or die(mysql_error());

echo "<div class="reves">";

// Affichage des rêves
while($db_data_reves = mysql_fetch_assoc($req)) {

   $id_reve = $db_data_reves['id'];
   
   // Affichage du rêve
   echo "<h2 id="r".$id_reve.""><a href="reve.php?id=".$id_reve."&amp;titre=";
   titre_url($db_data_reves['titre']);
   echo "">".$db_data_reves['titre']."</a></h2>
   <p class="reve_infos">Le ";
   datetime_fr($db_data_reves['date']);
   
   // Si le rêveur est inscrit
   if ($db_data_reves['pseudo_id'] >= 1) {
      echo ", <a href="reveur-infos.php?pseudo_id=".$db_data_reves['pseudo_id']."">".$db_data_reves['pseudo_inscrit']."</a>";
   }
   
   // Si le rêveur n'est pas inscrit
   else {
      if ($db_data_reves['email_publication'] == 'yes') {
         echo ", ".$db_data_reves['pseudo']." (<a href="mailto:".$db_data_reves['email']."">@</a>)";
      }
      else {
         echo ", ".$db_data_reves['pseudo'];
      }
   }
   $reve = $db_data_reves['reve'];
   $max_caracteres = 350;
   if (strlen($reve)>$max_caracteres) {
	   $max_caracteres=strrpos(substr($reve, 0, $max_caracteres), " ");
	   $reve = substr($reve, 0, $max_caracteres);
	   $reve .= " (...)";
   }
	 
   echo " a confié le rêve suivant à la boîte à rêves :</p>
   <p class="reve">$reve</p>";

   echo "<p class="right">";
   if (strlen($reve)>$max_caracteres) {
   	   echo "<a href="reve.php?id=".$id_reve."&amp;titre=";
	   titre_url($db_data_reves['titre']);
	   echo "">Lire la suite du rêve...</a> | ";
   }
   
   echo "<a href="reve.php?id=".$id_reve."&amp;titre=";
   titre_url($db_data_reves['titre']);
   echo "#add-interpretation">Proposer une interprétation</a>
   | <a href="reve.php?id=".$id_reve."&amp;titre=";
   titre_url($db_data_reves['titre']);
   echo "#interpretations">Lire les interpretations proposées</a>
   </p>
   
   <p>&nbsp;</p>";
   
}
 
WRInaute accro
Code:
// Si la personne est membre, on prend son nombre de rêves à afficher
if (!isset($_SESSION['nb_reves_aff'])) {
	$nb_reves_aff = '10';
}
else {
	$nb_reves_aff = $_SESSION['login_nb_reves_aff'];
}

$reves_bckid = $p*$nb_reves_aff;

// ###
// ~ A ~ J ~ O ~ U ~ T ~ E ~ R ~~~~~~~~~~~~~~~~~~~~~~~~~~~

// Sélection des rêves online
$sql = "SELECT COUNT(*) AS nb_reve_interpret, r_r.id
   FROM reves_interpretations r_i
   INNER JOIN reves_reves r_r
   ON r_i.id_reve = r_r.id
   WHERE r_r.activity='on'
   GROUP BY r_r.id
   ORDER BY r_r.id DESC
   LIMIT $reves_bckid,$nb_reves_aff";

$req = mysql_query($sql) or die(mysql_error());

while($db_data_reves = mysql_fetch_assoc($req)) 
{
   tab_nb_interpret[$db_data_reves['id']] = $db_data_reves['nb_reve_interpret'];
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ###

// Sélection des rêves online
$sql = "SELECT
        RR.id, RR.pseudo_id, RR.pseudo,
        RR.email, RR.email_publication, RR.titre,
        RR.reve, RR.date,
        RRVR.pseudo as pseudo_inscrit
FROM
        reves_reves RR

INNER JOIN reves_reveurs RRVR
ON RRVR.id = RR.pseudo_id

WHERE
        RR.activity='on'
GROUP BY
         RR.id
ORDER BY
         RR.id DESC
LIMIT
         $reves_bckid,$nb_reves_aff";

$req = mysql_query($sql) or die(mysql_error());

echo "<div class=\"reves\">";

// Affichage des rêves
while($db_data_reves = mysql_fetch_assoc($req)) {

   $id_reve = $db_data_reves['id'];

// ###
// ~ A ~ J ~ O ~ U ~ T ~ E ~ R ~~~~~~~~~~~~~~~~~~~~~~~~~~~

// la tu aura ta variable $nb_interpret correspondant au nombre d'interprétation de ton rêve
// il te suffira alors de faire un echo $nb_interpret; ou tu le souhaite
if (array_key_exists($id_reve, $tab_nb_interpret)) $nb_interpret = $tab_nb_interpret[$id_reve];
else $nb_interpret = 0;

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ###

   // Affichage du rêve
   echo "<h2 id=\"r".$id_reve."\"><a href=\"reve.php?id=".$id_reve."&amp;titre=";
   titre_url($db_data_reves['titre']);
   echo "\">".$db_data_reves['titre']."</a></h2>
   <p class=\"reve_infos\">Le ";
   datetime_fr($db_data_reves['date']);
   
   // Si le rêveur est inscrit
   if ($db_data_reves['pseudo_id'] >= 1) {
      echo ", <a href=\"reveur-infos.php?pseudo_id=".$db_data_reves['pseudo_id']."\">".$db_data_reves['pseudo_inscrit']."</a>";
   }
   
   // Si le rêveur n'est pas inscrit
   else {
      if ($db_data_reves['email_publication'] == 'yes') {
         echo ", ".$db_data_reves['pseudo']." (<a href=\"mailto:".$db_data_reves['email']."\">@</a>)";
      }
      else {
         echo ", ".$db_data_reves['pseudo'];
      }
   }
   $reve = $db_data_reves['reve'];
   $max_caracteres = 350;
   if (strlen($reve)>$max_caracteres) {
	   $max_caracteres=strrpos(substr($reve, 0, $max_caracteres), " ");
	   $reve = substr($reve, 0, $max_caracteres);
	   $reve .= " (...)";
   }
	 
   echo " a confié le rêve suivant à la boîte à rêves :</p>
   <p class=\"reve\">$reve</p>";

   echo "<p class=\"right\">";
   if (strlen($reve)>$max_caracteres) {
   	   echo "<a href=\"reve.php?id=".$id_reve."&amp;titre=";
	   titre_url($db_data_reves['titre']);
	   echo "\">Lire la suite du rêve...</a> | ";
   }
   
   echo "<a href=\"reve.php?id=".$id_reve."&amp;titre=";
   titre_url($db_data_reves['titre']);
   echo "#add-interpretation\">Proposer une interprétation</a>
   | <a href=\"reve.php?id=".$id_reve."&amp;titre=";
   titre_url($db_data_reves['titre']);
   echo "#interpretations\">Lire les interpretations proposées</a>
   </p>
   
   <p>&nbsp;</p>";
   
}

Code non testé, mais ça devrait fonctionner.
Tiens moi au courant ! ;)

Thierry
 
WRInaute passionné
Il me sort l'erreur :

Parse error: syntax error, unexpected '[' in /home/boiteare/www/index.php on line 45


Cette ligne 45 correspond à ce code :

Code:
tab_nb_interpret[$db_data_reves['id']] = $db_data_reves['nb_reve_interpret'];

J'ai essayé de mettre des " " mais ça ne marche pas non plus (même erreur).

C'est vraiment très sympa de m'aider en tout cas. J'apprécie énormément ton aide persévérante :).
 
WRInaute accro
yazerty a dit:
Il me sort l'erreur :

Parse error: syntax error, unexpected '[' in /home/boiteare/www/index.php on line 45


Cette ligne 45 correspond à ce code :

Code:
tab_nb_interpret[$db_data_reves['id']] = $db_data_reves['nb_reve_interpret'];

J'ai essayé de mettre des " " mais ça ne marche pas non plus (même erreur).
Normal, j'ai oublié le $tab_nb_interpret[$db_data_reves['id']] = $db_data_reves['nb_reve_interpret'];
Désolé. :?

yazerty a dit:
C'est vraiment très sympa de m'aider en tout cas. J'apprécie énormément ton aide persévérante :).
C'est normal, là ou je peux aider..ben je le fais avec plaisir. ;)
Pour une fois que je sais faire quelque chose ! :oops: :oops: :D
 
WRInaute passionné
Ca a l'air de très bien marcher :) !!!
Merci beaucoup pour cette très précieuse aide ! Je ne manquerais pas de te remercier sur le blog de la Boîte à rêves quand je posterai un billet à propos de cette amélioration notable, après quelques jours de tests grandeur nature (mais à priori tout va très bien :) ! ).

Mercii :D !

ps : si tu veux un bl pour un site dans ce billet, n'hésite pas à demander ;-).
 
WRInaute accro
..
...
Y a pas d'quoi ! ;)
Et bien je suis content que ça fonctionne.

merci pour le bl, mais je n'ai pas encore de site perso. :(
(pour ça que je n'ai pas de www)
 
WRInaute passionné
Arg, en fait il y a encore une petite coquille dans tout ce code :-/ : ça marche bien sur la permière page, mais pas sur les suivantes :-?.
Je ne comprends pas cette anomalie car "LIMIT $reves_bckid,$nb_reves_aff" est commun aux 2 reqûetes et marche très bien sur l'autre. De plus le calcul de ces variables est bien situé avant les 2 requêtes. D'où est-ce que ça peut-venir à ton avis :- ?
 
WRInaute passionné
Non il n'y a pas d'erreur.
Par exemple sur la page 2 (on y va en cliquant sur "page suivante" tout en bas de la page d'accueil), le rêve "Mowgli" a une interprétation (que j'ai postée pour tester). Mais sur la page 2 il n'est pas indiqué qu'il y en a, alors que cela marche sur la page d'accueil.

Par rapport à ton code, j'ai simplement modifié cela à la fin du script :
Code:
   echo "<a href=\"reve.php?id=".$id_reve."&amp;titre=";
   titre_url($db_data_reves['titre']);
   echo "#add-interpretation\">Proposer une interprétation</a>";
   
   if ($nb_interpret == '1') {
	   echo " | <a href=\"reve.php?id=".$id_reve."&amp;titre=";
	   titre_url($db_data_reves['titre']);
	   echo "#interpretations\">Lire la première interpretation proposée</a>";
   }
   elseif  ($nb_interpret > '1') {
	   echo " | <a href=\"reve.php?id=".$id_reve."&amp;titre=";
	   titre_url($db_data_reves['titre']);
	   echo "#interpretations\">Lire les $nb_interpret interpretations proposées</a>";
   }
   
   echo "</p>
   
   <p>&nbsp;</p>";
   
}
 
WRInaute accro
Oui j'ai compris.

En fait lorsque l'on sélectionne le nombre d'interprétation (COUNT), la requête par défaut de Mysql ne prend pas en compte s'il n'y a aucun interprétation (le faux problème que tu signalais dans un autre post). Ce ce fait lorsque tu va sur la page 2 il en zappe.

Explication: (exemple de base)

PAGE 1: de 1 à 3: (les trois premier)

id - COUNT
567 - 4
537 - 2
527 - 3

PAGE 2: de 4 à 6: (les trois premier)

id - COUNT
517 - 2
597 - 3
587 - 5

Quel est le problème ?
Et bien si dans la page 1 on avait un 0 il n'est pas indiqué, en revanche ça décalera la page 2...donc il manquera une donnée...
ainsi de suite (plus tu aura de page plus se sera la cata !) ;)

Bon je ne suis pas très doué pour les explications...


Je regarde, j'ai peut être une idée.
 
WRInaute accro
ok c'est Good !

Code:
"SELECT COUNT(r_i.id_reve) AS nb_reve_interpret, r_r.id
   FROM reves_interpretations r_i
   RIGHT JOIN reves_reves r_r
   ON r_i.id_reve = r_r.id
   WHERE r_r.activity='on'
   GROUP BY r_r.id
   ORDER BY r_r.id DESC
   LIMIT $reves_bckid,$nb_reves_aff;";

Remplace la requête de sélection pour le nombre d'interprétation par ça et ça roule....

En fait sur l'autre (comme tu l'avais remarqué) on ne prenait pas en compte lorsqu'il n'y avait pas d'interpréation. Cela créé évidement des trous, mais n'est pas dérangeant lorsque l'on ne fonctionne qu'avec une seule page. Et comme je ne savais pas...ben pour moi c'était good.

A présent on prend en compte, même lorsqu'il n'y a pas d'interprétation et la requête nous donnes le fameux 0. ;)

Voila.

Du coup il faut remplacer cette partie:
Code:
// ~ A ~ J ~ O ~ U ~ T ~ E ~ R ~~~~~~~~~~~~~~~~~~~~~~~~~~~

// la tu aura ta variable $nb_interpret correspondant au nombre d'interprétation de ton rêve
// il te suffira alors de faire un echo $nb_interpret; ou tu le souhaite
if (array_key_exists($id_reve, $tab_nb_interpret)) $nb_interpret = $tab_nb_interpret[$id_reve];
else $nb_interpret = 0;

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Par:
Code:
// ~ A ~ J ~ O ~ U ~ T ~ E ~ R ~~~~~~~~~~~~~~~~~~~~~~~~~~~

// la tu aura ta variable $nb_interpret correspondant au nombre d'interprétation de ton rêve
// il te suffira alors de faire un echo $nb_interpret; ou tu le souhaite
if (array_key_exists($id_reve, $tab_nb_interpret)) $nb_interpret = $tab_nb_interpret[$id_reve];
else $nb_interpret = -1;

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Et pour ta période de test tu regarde si $nb_interpret < 0 alors affiche 'PROBLEME'.
Tu test et regarde sur deux trois pages et ça tourne. ;)

Après tu pourra supprimer ce test et supprimer else $nb_interpret = -1;.
(même toute la partie)

Mais là ce sera bon, certain à 100% ! ;)
Sinon mon bl n'aurait pas été mérité. :roll:
 
WRInaute accro
..
...
Ca donne quoi à présent ? Des problèmes rencontrés ?

Je pense que ce dervait être bon à présent.
Si tu veux tu peux laisser le code qui gère en cas d'erreur (-1).
Comme ça, tu aura PROBLEME affiché, et tu le saura imédiatement,
mais là, il s'agira d'un problème au niveau de la base (problème lors d'un effacement ou autre), mais qui ne devrait théoriquement jamais arrivé (sauf coupure au moment d'une suppression de champs, champs supprimé que patiellement, etc...)
...
..
 
WRInaute passionné
Ca marche parfaitement bien :) !

Je te remercie beaucoup pour cette précieuse aide au développement de cette petite, mais indispensable, fonction.
 
Discussions similaires
Haut