Определите самый последний «тип голосования» для записи, возвращая 2 поля для HasVotedUp / Down? - PullRequest
0 голосов
/ 02 сентября 2011

У меня есть таблица SQL Server 2008, содержащая «голоса».Это могут быть «VoteUp» или «VoteDown» VoteTypeId (1 или 2 соответственно).

Каждый голос имеет отметку времени, когда голосование было вставлено в таблицу.
Каждая строка голосования принадлежитсообщение (FK PostId).
Каждая строка голосования принадлежит пользователю (FK UserId).

У меня есть запрос, чтобы вернуть список сообщений, и в этом же запросеЯ хочу определить, проголосовал ли текущий пользователь за этот пост "за" или "против" (или вообще не проголосовал).

В некоторых случаях в одном сообщении могут содержаться голоса как "вверх", так и "вниз", где пользователь изменил своивозражаю на более поздний срок (изменение голоса «за» на голосование «за»).В этом сценарии я хочу идентифицировать последнее голосование как соответствующее голосование (исходный нисходящий голос просто хранится в БД для исторических целей).

В идеале, я хотел бы, чтобы в поле было возвращено 2 простых поля BIT.запрос: HasVotedUp и HasVotedDown.

I может включать что-то вроде этого (сокращено для краткости), чтобы просто вернуть, был ли самый последний голос за этого пользователя / сообщениеголосованием «вверх» или «вниз», затем присваивайте свойства «HasVotedUp» и «HasVotedDown» в коде на основе возвращенного VoteTypeId ...

select p.id, p.body,
(select top 1 votetypeid from votes where userid = 1 and postid = p.id order by creationdate desc) as CurrentVoteTypeId
from posts p

... но мне было интересно, было ли такое же простое (новажно, эффективный) подход, который я мог бы использовать, чтобы вернуть 2 поля 'HasVotedUp / Down' в запросе, так что он находится на табличке, готов к использованию?

Этот вложенный подход был всем, что я придумал до сих порно я уверен, что это неэффективно?!

select cast((select count(1)
             from   votes
             where  userid = 1
                    and postid = p.id
                    and votetypeid = 1
                    and creationdate > (select creationdate
                                        from   votes
                                        where  userid = 1
                                               and postid = p.id
                                               and votetypeid = 2)) as bit) as
       HasVotedUp,
       cast((select count(1)
             from   votes
             where  userid = 1
                    and postid = p.id
                    and votetypeid = 2
                    and creationdate > (select creationdate
                                        from   votes
                                        where  userid = 1
                                               and postid = p.id
                                               and votetypeid = 1)) as bit) as
       HasVotedDown
from   posts p  

Ответы [ 2 ]

2 голосов
/ 02 сентября 2011

Это должно быть очень масштабируемым:

select p.id,
    CASE WHEN vt.votetypeid = 1 THEN 1 ELSE 0 END AS HasVotedUp,
    CASE WHEN vt.votetypeid = 2 THEN 1 ELSE 0 END AS HasVotedDown
from posts p left outer join
    (
        select v.postid, v.votetypeid
        from votes v inner join
        (
            select postid, userid, max(creationdate) as creationdate
            from votes
            group by postid, userid
        ) newest on v.postid = newest.postid and v.userid = newest.userid and v.creationdate = newest.creationdate
        where v.userid = 1
    ) vt on p.id = vt.postid
1 голос
/ 02 сентября 2011

Что хорошего для тебя?

SELECT p.id,
       O.*
FROM   posts p
       OUTER APPLY (SELECT MAX(CASE
                                 WHEN RN = 1 THEN votetypeid
                               END)            AS currentvotetypeid,
                           ISNULL(MAX(CASE
                                        WHEN votetypeid = 1 THEN 1
                                      END), 0) AS HasVotedUp,
                           ISNULL(MAX(CASE
                                        WHEN votetypeid = 2 THEN 1
                                      END), 0) AS HasVotedDown
                    FROM   (SELECT ROW_NUMBER() OVER (ORDER BY creationdate DESC) RN,
                                   *
                            FROM   votes
                            WHERE  userid = 1
                                   AND postid = p.id) T) O  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...