Click here to Skip to main content
15,914,390 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hey guys :-)

I want to improve my MySQL knowledge and have given me an weird requirement.
So please don't laugh ;-)

Target : show the last three point-entries for each user in several rows

There are two tables like:

table user:
user_id | name
1 | first_name
2 | second_name
3 | third_name

and

table point:
user_id | points
1 | 10
1 | 20
1 | 30
1 | 40
2 | 15
2 | 25
2 | 35
2 | 45
3 | 11
3 | 22
3 | 33

The result should look like:

user_id | name | points
1 | first_name | 40
1 | first_name | 30
1 | first_name | 20
2 | second_name | 45
2 | second_name | 35
2 | second_name | 25
3 | third_name | 33
3 | third_name | 22
3 | third_name | 11

I tried it with my basic joining- and subquery knowledge, but I ran into several MySql errors.
Limiting is not allowed with “IN” and so on.

What would you do, to solve this?
Posted
Comments
PIEBALDconsult 19-Nov-15 8:06am    
"What would you do, to solve this?" I'd use SQL Server instead.
expo82 19-Nov-15 17:52pm    
I like this answer and I will believe you.

But for now there is one problem:
"I want to improve my MySQL knowledge and have given me an weird requirement." ;-)

1 solution

What you are after is ranking within a category, where each name is the "category" and the points will be ranked for each name.

I found a neat trick on this post[^] which I used in this query
SQL
SET @prev := null;

SET @cnt := 0;

CREATE TEMPORARY TABLE IF NOT EXISTS table2 AS 
(
  SELECT U.user_id, user_name, points, 
      IF(@prev <> U.user_id, @cnt := 1, @cnt := @cnt + 1) AS rank, 
      @prev := U.user_id
  FROM user U
  JOIN point P ON U.user_id = P.user_id
  ORDER BY U.user_id, points DESC;
);
select user_id, user_name, points from table2 where rank < 4;

Sorry - sqlfiddle crashed on me so I haven't been able to test it fully.

Points to note - I've ordered the query by user_id ascending but points Descending as the points values seemed to increase. I haven't tried the query without the order on points. If there was a date/time when the points were gained then you could use that to get "the last 3 points" otherwise you might want to have a play around with emulating the sql Row_number function[^]
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900