2010-12-09 47 views
0

J'ai des tableaux de posts de blog - à chaque message ayant reçu un score. Les utilisateurs peuvent voter sur le message qui augmentera ou diminuera le score. Je veux seulement que les utilisateurs puissent voter une fois sur un poteau, ainsi j'ai un tableau de votes avec userId et postId. Lorsque l'utilisateur tente de voter, il vérifie d'abord s'il a déjà voté. Ils ne peuvent pas voter à nouveau, mais ils peuvent «annuler» ou inverser leur vote. Similaire à SO.Clause SQL Server WHERE en cas de doublons

Maintenant, tout fonctionne bien, mais quand la page est affichée, je veux montrer aux utilisateurs sur quels messages ils ont voté. Comme SO vous montre vos votes.

Je sélectionne les messages de la table des postes, et gauche joint externe sur la table des votes afin que je puisse vérifier si un utilisateur a voté.

SELECT * FROM ( 
    SELECT row_number() over (ORDER BY CreationDate DESC) AS rn, * 
    FROM (
    SELECT p.id, ownerUserId, p.CreationDate, COUNT(p.id) over (partition BY NULL) AS totalRecordCount, v.voteType 
     FROM Posts p 
    LEFT OUTER JOIN Votes v on p.id = v.postId 
    ) x 
) y 
WHERE 
rn BETWEEN 1 AND 20 

Cela me donne maintenant les messages, mais ils contiennent des entrées en double pour chaque vote. Je ne peux pas avoir ça parce que ça casse ma pagination.

J'ai essayé d'ajouter:

WHERE (v.userId = 1234 OR v.userId IS NULL) 

qui ne fonctionne pas vraiment, car évidemment, cela ne montrerait pas un poste que l'utilisateur actuel n'a pas voté, mais quelqu'un d'autre.

Savez-vous comment je peux y parvenir? Peut-il être fait dans une requête?

EDIT:

La requête ci-dessus est une version réduite. Fondamentalement, la requête renvoie les messages. C'est tout. Je montre ensuite un voteUpButton et voteDownButton sur la page, que les utilisateurs utilisent pour voter. Ce que je veux, c'est vérifier si un utilisateur a voté sur un post et montrer ce vote en augmentant le bouton.

Alors, où j'afficher le bouton, je veux faire quelque chose comme:

if (session.userObj.isLoggedIn() && len(postBoObj.get("voteType")) && postBoObj.get("voteType") == upVote) { 
    //show big up button 
else 
    //show normal up button 

Le voteType est stocké dans la table des votes, alors quand je suis entré la table après table et votes, et ajouté mon « OÙ (v.userId = 1234 OU v.userId IS NULL) "Je pourrais supposer que si voteType existait alors l'utilisateur actuellement connecté avait voté sur ce post. Mais comme je l'ai mentionné, cela ne montrera que les messages sur lesquels l'utilisateur a voté, ou aucun utilisateur n'a voté. S'il existe un message sur lequel un autre utilisateur a voté, le message "WHERE (v.userId = 1234 OR v.userId IS NULL)" l'exclut et le message ne sera jamais affiché.

J'espère que je me suis expliqué ok. Je veux fondamentalement exactement ce que fait Stackoverflow. Quand je clique sur une question, je vois les votes que j'ai faits. Quand Joe Blogs arrive sur la même question, il voit ses votes.

+0

Pouvez-vous montrer une sortie de l'échantillon, puis un exemple de la façon dont vous souhaitez qu'il apparaisse –

+0

?? voteTable = Votes – msi77

Répondre

1

Déplacer cette condition supplémentaire dans votre REJOIGNEZ:

SELECT * FROM ( 
    SELECT row_number() over (ORDER BY CreationDate DESC) AS rn, * 
    FROM (
    SELECT p.id, ownerUserId, p.CreationDate, COUNT(p.id) over (partition BY NULL) AS totalRecordCount, v.voteType 
     FROM Posts p 
    LEFT OUTER JOIN Votes v on p.id = v.postId AND v.UserID = 1234 /* <-- New bit here */ 
    ) x 
) y 
WHERE 
rn BETWEEN 1 AND 20 
+0

Merci! C'est exactement ce dont j'avais besoin. Maintenant, je pense à ce que vous avez fait est parfaitement logique. Seulement joindre pour cet utilisateur! – Terry