Eviter des doublons d'un rand sur une requête [Résolu]

SnapFAB 61 Messages postés samedi 10 novembre 2007Date d'inscription 5 mars 2011 Dernière intervention - 16 oct. 2010 à 13:34 - Dernière réponse : SnapFAB 61 Messages postés samedi 10 novembre 2007Date d'inscription 5 mars 2011 Dernière intervention
- 24 nov. 2010 à 03:50
Bonjour à tous,

Après beaucoup de recherche je n'ai pas trouvé de solution à mon problème. C'est pour cela que je me permets d'écrire sur ce forum à des vrais spécialistes.

Je fais une requête SQL avec la fonction RAND qui va m'afficher une image :
(cette requête marche très bien)



$req_carte = $bdd->query('select * FROM table order by rand() LIMIT 0,1') or die (print_r($bdd->errorInfo())) ;

while ($donnees = $req_carte->fetch()) {
$_SESSION['valeur1'] = $donnees['points'];
$_SESSION['image'] = '';
}
$req_carte->closeCursor(); // Termine le traitement de la requête req_carte


Vu que j'utilise souvent cette requête j'aurai souhaiter que le programme ne m'affiche pas deux fois la même photo pendant la session en cours.
Est-ce possible ?

Merci beaucoup pour vos réponses.
Afficher la suite 

Votre réponse

11 réponses

Meilleure réponse
ChasseurDeChimeres 292 Messages postés mercredi 7 novembre 2007Date d'inscription 15 janvier 2013 Dernière intervention - 19 oct. 2010 à 12:30
3
Merci
Salut;
En effet, petite erreur bête, j'ai mal concaténé les variables dans la boucle, sinon lors d'une énumération d'attributs il ne faut pas de ',' après le dernier, autant pour moi.
Tu vas devoir compter le nombre d'entrées du tableau et vérifier dans la boucle si ce n'est pas la dernière entrée qui tourne :

$nb_entries = count($_SESSION['old_img']);
$compte = 0;
$not_in = "(";
foreach($_SESSION['old_img'] as $intitule =>$param) {
  $compte ++;
  if($compte != $nb_entries){
    $not_in .= $param.", ";
  }
  else {
   $not_in .=  $param.')";
  }
}

$req_carte = $bdd->query("select * FROM table WHERE url_image_carte NOT IN ".$not_in." order by rand() LIMIT 0,1") or die (print_r($bdd->errorInfo())) ;


Si jamais cela ne marche pas, tu peux faire un "print" de la variable "$not_in" pour vérifier la syntaxe

Merci ChasseurDeChimeres 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 92 internautes ce mois-ci

Commenter la réponse de ChasseurDeChimeres
Meilleure réponse
kohntark 3708 Messages postés lundi 5 juillet 2004Date d'inscription 27 avril 2012 Dernière intervention - 20 oct. 2010 à 10:28
3
Merci
Re,

Je n'ai pas tout lu mais il y a peut être plus simple.
Le problème est qu'on ne connait pas le but exact de ce que tu veux faire et que ça dépend un peu de la structure de ton site.
Une question :
Que se passe t il si l'utilisateur appelle cette page plus de fois que le nombre de photos dont tu disposes ?
A vu de nez tu n'auras plus d'image affichée, ... et une petite quantité d'erreur.

De plus faire une requête à chaque appel de la page n'est peut être pas le plus judicieux, et le code me semble lourd.

Pourquoi ne pas charger 1 seule fois ta cinquantaine de photos ? Ca sera bien plus light.

Un truc comme ça par exemple :

<?php
if (empty($_SESSION['img'])) {
    $req = $bdd->query("SELECT points, url_image_carte FROM table ORDER BY RAND()");
    $_SESSION['img'] = $req->fetchAll();
}
$img = array_pop($_SESSION['img']);
// [...]
echo '';
?>


Cordialement,


Kohntark -

Merci kohntark 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 92 internautes ce mois-ci

Commenter la réponse de kohntark
kohntark 3708 Messages postés lundi 5 juillet 2004Date d'inscription 27 avril 2012 Dernière intervention - 16 oct. 2010 à 14:53
0
Merci
Salut,

Je ne suis pas sûr d'avoir bien compris.

Suffit de conserver en session toutes les images qui ont été affichées (dans un array), et de faire un "NOT LIKE ..." sur l'ensemble des éléments du tableau lors de la requête.
Non ?

C'est valable si le nombre d'images reste restreint. Si tu peux en avoir une centaine il faudra surement réfléchir à un autre système.

Plus d'infos seraient sans doute nécessaire.

Cordialement,

Kohntark -
Commenter la réponse de kohntark
SnapFAB 61 Messages postés samedi 10 novembre 2007Date d'inscription 5 mars 2011 Dernière intervention - 16 oct. 2010 à 21:37
0
Merci
Salut kohntark,

Merci pour ta réponse.

J'ai une cinquantaine d'image dans ma base, il n'y en aura pas plus.

Effectivement je ne connaissais pas "NOT LIKE" pour les requêtes mais comment peut on faire pour conserver les images qui ont été affichés dans la session ? Existe t-il des array pour les sessions ?

Désolé je suis débutant.

Cordialement,
SnapFAB
Commenter la réponse de SnapFAB
ChasseurDeChimeres 292 Messages postés mercredi 7 novembre 2007Date d'inscription 15 janvier 2013 Dernière intervention - 17 oct. 2010 à 22:02
0
Merci
Salut,
Il me semble que tu peux imbriquer des tableau ainsi :

$_SESSION['old_img'] = array();


et ensuite dans ta boucle :

array_push($_SESSION['old_img'], $donnees['id']);


et je ne sais pas trop comment ça marche mais il me semble que tu pourrais également utiliser "NOT IN()" dans ta requête sql.

bonne continuation
Commenter la réponse de ChasseurDeChimeres
SnapFAB 61 Messages postés samedi 10 novembre 2007Date d'inscription 5 mars 2011 Dernière intervention - 18 oct. 2010 à 04:50
0
Merci
Merci pour ta réponse chasseur

le array_push marche impeccable, par contre j'ai essayé le NOT IN et le NOT LIKE et j'ai exactement le même message d'erreur suivant :

Array ( [0] => 42000 [1] => 1064 [2] => 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 'WHERE url_image_carte NOT IN(Array)' at line 1 ) 1

LIGNE AVEC LE NOT IN :


$req_carte = $bdd->query("select * FROM table order by rand() LIMIT 0,1 WHERE url_image_carte NOT IN($_SESSION['old_img'])") or die (print_r($bdd->errorInfo())) ;

LIGNE AVEC LE NOT LIKE :


$req_carte = $bdd->query("select * FROM table order by rand() LIMIT 0,1 WHERE url_image_carte NOT LIKE '{$_SESSION['old_img']}'") or die (print_r($bdd->errorInfo())) ;

Que signifie cette erreur ?
Commenter la réponse de SnapFAB
SnapFAB 61 Messages postés samedi 10 novembre 2007Date d'inscription 5 mars 2011 Dernière intervention - 18 oct. 2010 à 09:25
0
Merci
J'ai corrigé mon erreur de syntaxe dans ma requête.



$req_carte = $bdd->query("select * FROM table WHERE url_image_carte NOT LIKE '{$_SESSION['old_img']}' order by rand() LIMIT 0,1") or die (print_r($bdd->errorInfo())) ;

Je n'ai plus aucun message d'erreur, par contre le NOT LIKE n'a pas l'air de fonctionner car des images déjà afficher reviennent tout de même (pourtant elles figurent bien dans l'array $_SESSION['old_img'])...
Résultat idem avec le NOT IN.

Que faire ?
Commenter la réponse de SnapFAB
ChasseurDeChimeres 292 Messages postés mercredi 7 novembre 2007Date d'inscription 15 janvier 2013 Dernière intervention - 18 oct. 2010 à 11:49
0
Merci
Salut;
As tu modifier mon code pour remplacer 'id' par 'url_image_carte'? (même si à mon gout c'est plus propre d'identifier les entrées d'une base de donnée par leur clé primaire) :

array_push($_SESSION['old_img'], $donnees['url_image_carte']);


et il me semble que les arguments de 'NOT IN' se précise comme ça :

SELECT * 
FROM table 
WHERE url_image_carte 
NOT IN ('img'1, 'img2', 'img3')
ORDER BY rand() 
LIMIT 0,1


du coup moi je verrais une petite boucle dans ton php pour construire un bout de la requete :

$not_in = "(";
foreach($_SESSION['old_img'] as $intitule =>$param) {
  $not_in .= "'$param', ";
}
$not_in .= ")";

$req_carte = $bdd->query("select * FROM table WHERE url_image_carte NOT IN ".$not_in." order by rand() LIMIT 0,1") or die (print_r($bdd->errorInfo())) ;


j'ai pas tester mais l'idée est là, sinon peut-être que ton erreur n'a rien à voir avec ça.
Commenter la réponse de ChasseurDeChimeres
SnapFAB 61 Messages postés samedi 10 novembre 2007Date d'inscription 5 mars 2011 Dernière intervention - 19 oct. 2010 à 07:01
0
Merci
Merci pour tes réponses et ta patience chasseur

Effectivement j'ai modifier ton code pour remplacer 'id' par 'url_image_carte'.

Je ne suis malheureusement toujours pas arriver à mes fins :

le NOT IN m'indique un message d'erreur, et le NOT LIKE ne m'indique pas d'erreur mais affiche tout de même des doublons.



$req_carte = $bdd->query('select * FROM table WHERE url_image_carte NOT IN ".$not_in." order by rand() LIMIT 0,1') or die (print_r($bdd->errorInfo())) ;

Voici le code d'erreur que je n'arrive pas à déchiffrer :
Array ( [0] => 42000 [1] => 1064 [2] => 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 '".$not_in." order by rand() LIMIT 0,1' at line 1 ) 1
Commenter la réponse de SnapFAB
SnapFAB 61 Messages postés samedi 10 novembre 2007Date d'inscription 5 mars 2011 Dernière intervention - 20 oct. 2010 à 07:47
0
Merci
Salut chasseur,
Génial ça marche, merci beaucoup pour ton aide

Il y avait encore une petite erreur de syntaxe dans le code et il a fallu rajouter une condition au début pour vérifier si le tableau est vide.

Tout fonctionne, un grand merci à toi.

Voici le code final pour les personnes intéressées :

$nb_entries = count($_SESSION['old_img']); //on compte les entrées qu'il y a dans le tableau S_SESSION
$compte = 0;
$not_in = "('";
foreach($_SESSION['old_img'] as $intitule =>$param) {
$compte ++;
if($compte != $nb_entries){
$not_in .= $param."', '";
}
else {
$not_in .= $param. "')";
}
}

// test si la variable est vide
if(empty($_SESSION['old_img'])) {
$req_carte = $bdd->query('select * FROM table order by rand() LIMIT 0,1 ') or die (print_r($bdd->errorInfo())) ;
} else {
$req_carte = $bdd->query("select * FROM table WHERE url_image_carte NOT IN ".$not_in." order by rand() LIMIT 0,1") or die (print_r($bdd->errorInfo())) ;
}

while ($donnees = $req_carte->fetch()) // la boucle qui recherche les données et les enregistres
{
$_SESSION['valeur1'] = $donnees['points'];
$_SESSION['image'] = '';
array_push($_SESSION['old_img'], $donnees['url_image_carte']);
}

$req_carte->closeCursor(); // Termine le traitement de la requête req_carte
Commenter la réponse de SnapFAB
SnapFAB 61 Messages postés samedi 10 novembre 2007Date d'inscription 5 mars 2011 Dernière intervention - 24 nov. 2010 à 03:50
0
Merci
Re kohntark,

Désolé pour le retard de ma réponse mais je n'ai pas reçu le mail comme quoi il y avait une nouvelle réponse.

Effectivement ta réponse me semble également très intéressante.
Je vais étudier le array_pop.

Merci beaucoup.

SnapFAB
Commenter la réponse de SnapFAB

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.