Précédent   Forum des professionnels en informatique > Bases de données > MySQL > Requêtes
Requêtes Forum d'entraide sur les requêtes MySQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 24/02/2011, 20h41   #1
Futur Membre du Club
 
Damien
Inscription : juillet 2009
Messages : 50
Détails du profil
Informations personnelles :
Nom : Damien

Informations forums :
Inscription : juillet 2009
Messages : 50
Points : 16
Points : 16
Par défaut Coincé sur condition dans requête

Bonjour à tous !

Après recherche, je post ici un problème qui me reste sur les bras...
En terme de "condition" dans MySQL, j'ai vu que le CASE fonctionne. Mais là, ma condition semble un peu trop complexe en l'occurence

Déjà, ma requête actuelle :

Code :
1
2
3
4
5
SELECT P.post_id, 
  T.topic_id, 
  (SELECT COUNT(note_pro) FROM notes WHERE note_pro = '1' AND post_id = P.post_id) AS NbPro 
FROM topics T, posts P 
WHERE T.topic_id = P.topic_id AND T.topic_id = '1';
Celle-ci pioche dans 3 tables : "topics", "posts", "notes".
"topics" et "posts" sont liées par "topic_id", et "posts" et "notes" sont liées par "post_id". Jusque là, assez standard pour un forum.
Le résultat de cette requête donne le nombre de résultat "positif" (note_pro, à l'inverse de note_con) pour chaque post dans un topic donné (ici le '1').

Maintenant, je soulève le problème ; la table "notes" est également reliée, nécessairement, à la table "users" par "user_id" (pour empecher double-vote).

Le but : ajouter un 4e champs à mon résultat, un booléen pour être précis, du type "deja_vote", qui serait sur "true" si l'user connecté à déjà voté sur un post, ou "false" si ça n'est pas le cas.

Du coup, faut qu'avant requête je récupère le user_id en session de la personne, jusque là no-soucis. Ensuite, c'est là où ça coince ;
il faut que ma requête détecte, en tournant sur "notes", si à un moment le "user_id" est égal à celui que j'ai, et si à UN SEUL moment c'est le cas, passer le booléen "deja_vote" à true et le laisser tel quel.


Bref, j'suis complètement paumé.

Si quelqu'un a suffisement de pitié pour se défoncer le cerveau à coup d'pelle pour m'aider... J'lui en serait vraiment vraiment reconnaissant
WibiMaster est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/02/2011, 06h34   #2
Rédacteur/Modérateur

 
Avatar de Antoun
 
Homme Antoine Dinimant
Consultant en Business Intelligence
Inscription : octobre 2006
Messages : 5 854
Détails du profil
Informations personnelles :
Nom : Homme Antoine Dinimant
Âge : 42
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Consultant en Business Intelligence
Secteur : Conseil

Informations forums :
Inscription : octobre 2006
Messages : 5 854
Points : 9 544
Points : 9 544
On va commencer par réécrire ta requête de base rationnellement, càd avec un indentation, des jointures normalisées, en remplaçant la sous-requête inutile par un LEFT JOIN et en supprimant les apostrophes autour des nombres :

Code :
1
2
3
4
5
6
7
8
SELECT P.post_id, 
  T.topic_id,
  SUM(note_pro) AS NbPro 
FROM topics T
  INNER JOIN posts P ON T.topic_id = P.topic_id 
  LEFT JOIN notes N ON N.post_id = P.post_id AND N.note_pro = 1
WHERE T.topic_id = 1 
GROUP BY P.post_id, T.topic_id
Si je fais maintenant l'hypothèse que note_pro et note_con sont des flags qui valent 0 ou 1, on voit qu'il suffit d'additionner les note_pro pour avoir le nombre de votes positif. Cela permet de ne pas éliminer les votes négatifs de la requête, et donc de rechercher si l'utilisateur ($user) a déjà voté :

Code :
1
2
3
4
5
6
7
8
9
10
11
SELECT P.post_id, 
  T.topic_id,
  COUNT(note_pro) AS NbPro,
  MAX(CASE WHEN N.user_id = $user THEN 1 ELSE 0 END) AS deja_vote
-- variante spécifique à MySQL :
--MAX(N.user_id = $user) as deja_vote
FROM topics T
  INNER JOIN posts P ON T.topic_id = P.topic_id 
  LEFT JOIN notes N ON N.post_id = P.post_id 
WHERE T.topic_id = 1 
GROUP BY P.post_id, T.topic_id
__________________
Antoun
Expert SQL, BO, Essbase

La bible d'Essbase est parue !
Antoun est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 25/02/2011, 08h31   #3
Futur Membre du Club
 
Damien
Inscription : juillet 2009
Messages : 50
Détails du profil
Informations personnelles :
Nom : Damien

Informations forums :
Inscription : juillet 2009
Messages : 50
Points : 16
Points : 16
[big edit]
Bon, j'efface toute ma réponse et je reprends ^^

Après une ou deux modifs, voilà, ca fonctionne

Code :
1
2
3
4
5
6
7
8
9
10
SELECT P.post_id, T.topic_id, SUM( note_pro ) AS NbPro, SUM( note_con ) AS NbCon, MAX( 
	CASE WHEN N.user_id =  '1'
	THEN 1 
	ELSE 0 
	END ) AS deja_vote
FROM topics T
INNER JOIN posts P ON T.topic_id = P.topic_id
LEFT JOIN notes N ON N.post_id = P.post_id
WHERE T.topic_id =1
GROUP BY P.post_id, T.topic_id
J'ai méler tes deux exemples pour aboutir à ça ; le SUM est mieux que le COUNT ici, puisqu'il ne prends comme tu l'as dit que les résultat positifs. Et j'ai retiré la condition "AND N.note_pro = 1", pour pouvoir récupérer la totalité des résultats.


Encore merci, c'est parfait !!!
WibiMaster est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 16h48.


 
 
 
 
Partenaires

Hébergement Web