MySQL Возвращает 1 или 0 на основе найденного идентификатора

0

Вот фрагмент таблиц:

USER

|  USER_UID  |  FIRSTNAME  |  LASTNAME  | 
    abc123         bob          smith
    def456         rob          smithies 
    ghi789         john         clark

СОБЫТИЕ

| GUID | NAME |  
  ev1   event1
  ev2   event2
  ev3   event3

USER_EVENT

| USER_EVENT_ID | USER_UID | EVENT_UID | 
       1            abc123     ev1
       2            def456     ev2
       3            ghi789     ev3

EVENT_VOTE

| EVENT_VOTE_ID | USER_UID | EVENT_UID | 
         1         def456      ev1       (user2 voted for user1 event)

У меня есть следующий запрос, который возвращает событие с количеством голосов и ранга на основе этого:

SELECT t.*, @curRank := @curRank + 1 AS rank
FROM ( SELECT e.guid,
              e.name,
              ( SELECT COUNT(ev.event_vote_id) 
                FROM event_vote ev 
                WHERE ev.event_uid = e.guid
              ) AS votes
              FROM event e
      ) AS t
CROSS JOIN (SELECT @curRank := 0) r
ORDER BY votes DESC

Я также хочу вернуть 1 или 0, если пользователь не имеет права голоса или нет.

Пользователь не имеет права голоса, если:

  • пользователь является владельцем события.

  • пользователь уже проголосовал за это событие (пользователи uid и event uid находятся в event_vote).

Следующий код после ... голосов AS дал мне правильный ответ, если пользователь уже голосовал, но не был, если им принадлежало это событие.

,(
    SELECT COUNT(*)
    FROM event_vote ev
    WHERE ev.event_uid = e.guid
    AND ev.user_uid = '{$user_uid}'
 ) AS ineligible

Ожидаемый результат (с точки зрения пользователя 2s при просмотре всех событий)

guid: ev1
name: event1
votes: 1 
rank: 1
ineligible: 1 (already voted).

guid: ev2
name: event2
votes: 0
rank: 2
ineligible: 1 (user owns this event)

guid: ev3
name: event3
votes: 0 
rank: 3
ineligible: 0 (user doesn't own this event and has yet to vote).
  • 0
    the user has already voted for that event ... можете ли вы указать, где это происходит в ваших данных?
  • 0
    в таблице event_vote, извините, я обновлю это сейчас, опечатка.
Теги:
where
join
count

2 ответа

1
Лучший ответ

Вы можете использовать этот запрос в case when выражение даёт 1 или null. Это агрегируется как count(distinct...) который дает 1 только тогда, когда в агрегированных значениях по крайней мере один 1, а 0 - в противном случае:

SELECT      t.*,
            @curRank := @curRank + 1 AS rank 
FROM        (
                SELECT     u.user_uid,
                           e.guid, 
                           e.name, 
                           count(ev.user_uid) votes, 
                           count(distinct 
                               case when u.user_uid in (ev.user_uid, ue.user_uid)
                                    then 1 
                               end) ineligible 
                FROM       user u
                CROSS JOIN event e
                INNER JOIN user_event ue
                        ON ue.event_uid = e.guid
                LEFT JOIN  event_vote ev
                        ON ev.event_uid = e.guid
                GROUP BY   u.user_uid, 
                           e.guid
                ORDER BY   votes desc,
                           e.guid,
                           u.user_uid
            ) as t
CROSS JOIN (SELECT @curRank := 0) r
WHERE      t.user_uid = 'def456'
ORDER BY   votes desc,
           guid, 
           user_uid

Посмотрите, как это работает на rextester.com.

Имейте в виду, что, когда вы используете такие переменные, вы должны вынудить порядок во внутреннем запросе. Если вы делаете это только во внешнем запросе, это происходит слишком поздно, как только переменные выражения уже были оценены. Это может часто работать, поскольку оптимизатор может учитывать внешний order by, но он не гарантируется.

0

вам нужно будет проверить, существует ли User_UID для проголосованного события в таблице User_Event. Если это так, то избиратель является владельцем.

что-то вроде: (PSEUDO Я не рядом с компилятором)

     IF EXISTS (Begin
        select User_Event_Id 
        from User_event 
        where User_UId = @user_uid 
        (@user_uid the user trying to vote) 
        and where Event_Id = @Event 
        (@Event = event of the id, the user is trying to vote for)
        End)
        Begin
        if(--Check if user has voted for event (code you already wrote)
        --User is eligible
        else
        --User not eligible
        End

    ELSE
        --User not eligible

Но, может быть, лучше просто потратить время, чтобы объединить эти два запроса без результата для операторов if.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню