Page 1 sur 1

Appliquer un filtre sur une requete

Posté : 11 févr. 2008, 16:17
par VaN
Bonjour,

je rencontre un problème avec une de mes requêtes.

J'aimerai sélectionner tous les champs d'une table CONCOURS, dont l'utilisateur n'a pas spécifié qu'il ignorait ou avait fait ce concours. je m'explique :

Une table CONCOURS que voici :
CREATE TABLE `concours` (
`concours_id` int(11) NOT NULL auto_increment,
`concours_user_id` int(11) NOT NULL,
`concours_site_id` int(11) NOT NULL,
`concours_url` text NOT NULL,
`concours_reglement_url` text NOT NULL,
`concours_start_date` datetime NOT NULL,
`concours_end_date` datetime NOT NULL,
`concours_type` tinyint(4) NOT NULL,
`concours_participation` tinyint(11) NOT NULL,
`concours_qs` enum('Oui','Non') NOT NULL,
`concours_nb_reponses` tinyint(4) NOT NULL,
`concours_lots` text NOT NULL,
`concours_rating` tinyint(4) NOT NULL,
`concours_activated` tinyint(4) NOT NULL,
PRIMARY KEY (`concours_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
Et une table USERS, que voici :
CREATE TABLE `users` (
`user_id` int(11) NOT NULL auto_increment,
`user_login` text character set latin1 collate latin1_general_cs NOT NULL,
`user_pass` text character set latin1 collate latin1_general_cs NOT NULL,
`user_mail` text NOT NULL,
`user_level` tinyint(4) NOT NULL,
`user_activated` tinyint(4) NOT NULL,
`user_activation_key` text character set latin1 collate latin1_general_cs NOT NULL,
`user_logged` tinyint(4) NOT NULL,
`user_last_session` datetime NOT NULL,
`user_last_ip` text NOT NULL,
`user_points` int(11) NOT NULL,
`user_parrain_id` int(11) NOT NULL,
`user_concours_done` text NOT NULL,
`user_concours_ignored` text NOT NULL,
`user_scoot_activated` tinyint(4) NOT NULL,
PRIMARY KEY (`user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=24 ;
Dans cette table USERS, il y'a les champs user_concours_done et user_concours_ignored, ou je stocke les ID des concours que l'utilisateur a fait/ignore, en séparant chaque concours_id par un ";".

Maintenant, ce que j'aimerai faire, c'est appliquer sur une large liste de concours un filtre, qui permettrait de n'afficher QUE les concours ou les checkbox "FAIT" et "IGNORE" n'ont pas été cochées, autrement dit, ou l'id de ce concours ne se retrouve ni dans le champs user_concours_done, ni dans le champs user_concours_ignored.

J'ai donc tenté une requête, que voici :
$sql = 	"SELECT concours_id, site_name, concours_end_date, concours_type_title, concours_rating
			FROM ".$prefixe."concours, ".$prefixe."concours_type, ".$prefixe."sites, ".$prefixe."users
			WHERE concours_type = concours_type_id
			AND concours_site_id = site_id
			AND concours_activated = 1
			and user_id = '".$_SESSION['user_id']."'
			AND user_concours_done != % ;concours_id; % ";
et qui pour le moment me renvoie
#1064 - Erreur de syntaxe près de '%' à la ligne 1
J'imagine bien que ma syntaxe n'est pas correcte. J'ai tenté d'utiliser le signe SQL %, car il me semblait qu'il signifiait "n'importe quoi".

Quelqu'un pourrait-il me donner un coup de main pour cette requête ?

Merci d'avance

Posté : 11 févr. 2008, 17:03
par d0m
Si tu peux encore, il faudrait revoir la conception de ta base de données.

C'est un mauvais procédé que de stocker plusieurs id dans un champ, il vaut mieux faire une (ou 2) table(s) d'association utilisateur - concours :

Code : Tout sélectionner

CREATE TABLE concours_done `user_id` int(11) NOT NULL `concours_id` int(11) NOT NULL CREATE TABLE concours_ignore `user_id` int(11) NOT NULL `concours_id` int(11) NOT NULL
Tu peux faire une seule table si il y a un ou exclusif c'est à dire soit le concours est fait, soit il est ignoré et donc avec par exemple un drapeau en plus à 1 si fait, 0 si ignoré:

Code : Tout sélectionner

CREATE TABLE user_concours `user_id` int(11) NOT NULL `concours_id` int(11) NOT NULL `done` int tinyint(4) NOT NULL

Posté : 11 févr. 2008, 17:16
par Sékiltoyai
Ou alors un champ SET pour stocker l'ensemble des propriétés du concours, même si elles sont exclusives…

Posté : 11 févr. 2008, 17:27
par VaN
Si tu peux encore, il faudrait revoir la conception de ta base de données.

C'est un mauvais procédé que de stocker plusieurs id dans un champ, il vaut mieux faire une (ou 2) table(s) d'association utilisateur - concours :

Code : Tout sélectionner

CREATE TABLE concours_done `user_id` int(11) NOT NULL `concours_id` int(11) NOT NULL CREATE TABLE concours_ignore `user_id` int(11) NOT NULL `concours_id` int(11) NOT NULL
J'avais pensé à ça au début lorsque j'ai crée mes tables, mais je me suis dit que ce n'etait pas une bonne idée, car plus on avance dans le temps, et plus ces deux tables vont devenir volumineuses, car à la fois ne nombre d'utilisateurs ET le nombre de concours recencés (et donc potentiellement fait/ignoré) vont grandir, faisant croitre ces tables de manières exponentielles.

C'est tout de même mieux que ma méthode actuelle ?

Posté : 11 févr. 2008, 17:31
par Sékiltoyai
C'est une méthode utilisée absolument partout, si ca peut répondre à ta question :)
Le fait est qu'avec des index bien placés, une table volumineuse n'est pas problématique (MySQL sait gérer des tables de plusieurs TeraOctets), car la recherche sera optimisée. En plaçant concaténant tes données dans un champ, tu te prives l'utilisation de toutes les fonctionnalités de jointure de MySQL, et donc en l'occurence tu risques de faire plus de requètes et de plomber ton serveur.

Posté : 11 févr. 2008, 17:36
par VaN
Ok, vais tenter de modifier ça toute de suite alors.

Deux questions concernant cette table. Créer un champ d'ID unique en début de table est totalement inutile ?

Créer cette table signifie qu'a chaque fois qu'un utilisateur ou un concours est ajouté, je dois créer toutes les correspondances dans la table, en spécifiant que le concours n'est pour le moment ni fait ni ignoré ?

Par exemple j'ai 5 concours répertoriés, un nouvel utilisateur s'inscrit, il faut que je crée 5 lignes, avec ce user_id, et chacun des concours_id. Ca fait lourd nan ?

EDIT : Bon ayé, je viens de refaire mes tables, et effectivement, c'est beaucoup plus facile pour effectuer ce que je voulais faire. Merci.