Reputation: 48450
I have a MySQL table that looks like the following:
player_rankings | CREATE TABLE `player_rankings` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`award_id` int(11) NOT NULL,
`rank_1` int(11) DEFAULT NULL,
`rank_2` int(11) DEFAULT NULL,
`rank_3` int(11) DEFAULT NULL,
`rank_4` int(11) DEFAULT NULL,
`rank_5` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `user_id` (`user_id`,`award_id`)
)
rank_1
through rank_5
contain ids of players that I have in a different table, but for the purpose of this query, it isn't relevant. What I am trying to do is count how many times a value shows up in each rank_*
column and then give it the following amount of points:
rank_1
- 5 pointsrank_2
- 4 pointsrank_3
- 3 pointsrank_4
- 2 pointsrank_1
- 1 pointThe end result would sort from highest to lowest (descending) the player ids with their total point count.
Upvotes: 2
Views: 1249
Reputation: 92785
Try
SELECT user_id, SUM(6 - rank) points
FROM
(
SELECT rank,
CASE rank
WHEN 1 THEN rank_1
WHEN 2 THEN rank_2
WHEN 3 THEN rank_3
WHEN 4 THEN rank_4
WHEN 5 THEN rank_5
END user_id
FROM player_rankings t CROSS JOIN
(
SELECT 1 rank UNION ALL
SELECT 2 UNION ALL
SELECT 3 UNION ALL
SELECT 4 UNION ALL
SELECT 5
) i
) q
GROUP BY user_id
ORDER BY points DESC
The idea behind this query is to first unpivot your table, then calculate points per user_id while grouping and then order the resultset descending by points. All in one query.
Sample output:
| USER_ID | POINTS | |---------|--------| | 50 | 13 | | 10 | 12 | | 30 | 12 | | 20 | 9 | | 40 | 5 | | 60 | 4 | | 70 | 3 | | 80 | 2 |
Here is SQLFiddle demo
Upvotes: 0
Reputation: 43434
To get the sum of points per rank:
SELECT user_id,
sum(rank1Points) rank1Points,
sum(rank2Points) rank2Points,
sum(rank3Points) rank3Points,
sum(rank4Points) rank4Points,
sum(rank5Points) rank5Points
FROM (
SELECT pr.rank_1 user_id, count(*) * 5 rank1Points, 0 rank2Points, 0 rank3Points, 0 rank4Points, 0 rank5Points
FROM player_rankings pr
GROUP BY pr.rank_1
UNION ALL
SELECT pr.rank_2, 0, count(*) * 4, 0, 0, 0
FROM player_rankings pr
GROUP BY pr.rank_2
UNION ALL
SELECT pr.rank_3, 0, 0, count(*) * 3, 0, 0
FROM player_rankings pr
GROUP BY pr.rank_3
UNION ALL
SELECT pr.rank_4, 0, 0, 0, count(*) * 2, 0
FROM player_rankings pr
GROUP BY pr.rank_4
UNION ALL
SELECT pr.rank_5, 0, 0, 0, 0, count(*)
FROM player_rankings pr
GROUP BY pr.rank_5
) s
GROUP BY user_id
Fiddle here.
To get the total number of points together in one column:
SELECT user_id,
sum(rankPoints) rankPoints
FROM (
SELECT pr.rank_1 user_id, count(*) * 5 rankPoints
FROM player_rankings pr
GROUP BY pr.rank_1
UNION ALL
SELECT pr.rank_2, count(*) * 4
FROM player_rankings pr
GROUP BY pr.rank_2
UNION ALL
SELECT pr.rank_3, count(*) * 3
FROM player_rankings pr
GROUP BY pr.rank_3
UNION ALL
SELECT pr.rank_4, count(*) * 2
FROM player_rankings pr
GROUP BY pr.rank_4
UNION ALL
SELECT pr.rank_5, count(*)
FROM player_rankings pr
GROUP BY pr.rank_5
) s
GROUP BY user_id
Fiddle here.
Upvotes: 1
Reputation: 2719
For your table structure may be good solution is calculate all in script. Just get all rows and then calculate.
If you want make all in one SQL query then you can try use UNION for 5 subqueries
SELECT user_id, rank FROM(
SELECT rank_1 AS user_id, 5 AS rank FROM player_rankings
UNION
SELECT rank_2 AS user_id, 4 AS rank FROM player_rankings
....
) AS u;
There is not working script, but I hope you understand my solution
Upvotes: 0