MySQL Returning highest ranked event for a user

爷,独闯天下 提交于 2020-01-05 00:38:01

问题


I currently use the following query to get the details of every user.

SELECT u.*, sums.total_votes, sums.no_of_events
FROM user u
LEFT JOIN
(
  SELECT
    us.user_uid,
    count(ev.event_vote_id) AS total_votes 
    count(distinct ue.event_uid) AS no_of_events
  FROM user_event ue
  LEFT JOIN event_vote ev
  ON ev.event_uid = ue.event_uid
  GROUP BY ue.user_uid
) sums ON sums.user_uid = u.user_uid

However, I wish to also return the rank of their highest voted event (out of all events - not just their own).

USER

|  USER_UID  |  FIRSTNAME  |  LASTNAME  | 
       1         bob          smith
       2         rob          smithies 
       3         john         clark

EVENT

| GUID | NAME |  
  101   event1
  102   event2
  103   event3

USER_EVENT

| USER_EVENT_ID | USER_UID | EVENT_UID | 
       1001           1         101
       1002           2         102
       1003           1         103

EVENT_VOTE

| EVENT_VOTE_ID | USER_UID | EVENT_UID | 
       2001            2       101       
       2002            3       101
       2003            2       103

Expected Result

user_uid: 1
firstname: bob
lastname: smith
votes: 3        // 2 for 101, 1 for 103.
no_of_events: 2
bestRank: 1 (1st)    // ranked 1st and 2nd but 1st is higher.

user_uid: 2
firstname: rob
lastname: smithies
votes: 0      
no_of_events: 1
bestRank: 3 (3rd)

回答1:


This query has 3 parts

  1. Your Original query to calculate total events for each users
  2. Ranking all events for most votes.
  3. Filtering what events has the best ranking

In the demo you can also see three query so you can debug the partial results.

Current output also is a partial result, to get your desire result you need add

WHERE R.event_uid IS NULL

SQL DEMO

Final version

SELECT *
FROM (  SELECT u.*, sums.total_votes, sums.no_of_events
        FROM user u
        JOIN ( SELECT ue.user_uid,
                      count(ev.event_vote_id) AS total_votes, 
                      count(distinct ue.event_uid) AS no_of_events
               FROM user_event ue
               LEFT JOIN event_vote ev
                 ON ev.event_uid = ue.event_uid
               GROUP BY ue.user_uid
             ) as sums
          ON u.user_uid  = sums.user_uid 
     ) as U
JOIN (  SELECT T.*,
               @rank := @rank + 1 as rn,
               @dense := if (@votes = votes,
                             @dense,
                             if(@votes := votes, @rank, @rank)
                            ) as dense
        FROM (
              SELECT 
                     e.guid as event_uid,
                     ue.user_uid, 
                     count(ev.event_uid) AS votes             
              FROM event e
              JOIN user_event ue
                ON e.guid = ue.event_uid
              LEFT JOIN event_vote ev
                ON ev.event_uid = ue.event_uid      
              GROUP BY e.GUID, ue.user_uid
              ORDER BY count(ue.event_uid) DESC
             ) as T
        CROSS JOIN (SELECT @rank := 0, @dense := 0, @votes := 0 ) as vars
        ORDER BY votes desc, event_uid
)  as Q
ON U.user_uid = Q.user_uid
LEFT JOIN (  SELECT T.*,
               @rank2 := @rank2 + 1 as rn,
               @dense2 := if (@votes2 = votes,
                             @dense2,
                             if(@votes2 := votes, @rank2, @rank2)
                            ) as dense
        FROM (
              SELECT 
                     e.guid as event_uid,
                     ue.user_uid, 
                     count(ev.event_uid) AS votes             
              FROM event e
              JOIN user_event ue
                ON e.guid = ue.event_uid
              LEFT JOIN event_vote ev
                ON ev.event_uid = ue.event_uid      
              GROUP BY e.GUID, ue.user_uid
              ORDER BY count(ue.event_uid) DESC
             ) as T
        CROSS JOIN (SELECT @rank2 := 0, @dense2 := 0, @votes2 := 0 ) as vars
        ORDER BY votes desc, event_uid
)  as R
ON  Q.user_uid = R.user_uid
AND Q.rn > R.rn
-- WHERE  R.event_uid IS NULL

OUTPUT

| USER_UID | FIRSTNAME | LASTNAME | total_votes | no_of_events | event_uid | user_uid | votes | rn | dense | event_uid | user_uid |  votes |     rn |  dense |
|----------|-----------|----------|-------------|--------------|-----------|----------|-------|----|-------|-----------|----------|--------|--------|--------|
|        1 |       bob |    smith |           3 |            2 |       101 |        1 |     2 |  1 |     1 |    (null) |   (null) | (null) | (null) | (null) |
|        1 |       bob |    smith |           3 |            2 |       103 |        1 |     1 |  3 |     2 |       101 |        1 |      2 |      1 |      1 |
|        2 |       rob | smithies |           1 |            3 |       102 |        2 |     1 |  2 |     2 |    (null) |   (null) | (null) | (null) | (null) |
|        2 |       rob | smithies |           1 |            3 |       104 |        2 |     0 |  4 |     4 |       102 |        2 |      1 |      2 |      2 |
|        2 |       rob | smithies |           1 |            3 |       105 |        2 |     0 |  5 |     4 |       102 |        2 |      1 |      2 |      2 |
|        2 |       rob | smithies |           1 |            3 |       105 |        2 |     0 |  5 |     4 |       104 |        2 |      0 |      4 |      4 |


来源:https://stackoverflow.com/questions/49257687/mysql-returning-highest-ranked-event-for-a-user

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!