Jump to content

how to stop a query once a certain row is reached


Go to solution Solved by Shadowing,

Recommended Posts

Having a issue on figuring how to do this. I have a table with a unique I'd with a int column for a rank system.

 

I need to figure out what rank a player is. Right now I'm selecting the players rank and then doing a count all rows where rank is >= $players_rank

 

I'm using pigmentation links so I'm trying to figure out what page the user would be on. The problem is in a rare situation where more then one player has the same amount of rank and the rank is split up over two pages.

 

Hope I explained this good enough. Its a pickle of a problem :P

Pagination. It's called pagination. Not pigmentation. :P

 

You know how many rows you want on a page, right? Use a LIMIT clause to reflect that.

SELECT fields FROM table WHERE rank >= $players_rank ORDER BY rank ASC LIMIT 50 /* 50 rows per page */

I found this example online but I don't understand it enough to edit it

 

 

SELECT COUNT(*) FROM game ui
     WHERE (ui.points,ui.id >= (uo.points, uo.id)
     ) AS rank
     FROM game uo
     WHERE id = @id

Pretty sure you don't want the ui.id part.

SELECT COUNT(*) + 1 FROM table WHERE points > players points /* and then +1 */
or
SELECT COUNT(*) FROM table WHERE points >= players points
One of those will give you the rank number you want, and it depends on what rank number you would give someone if they were tied for first place. Say three people score A=10, B=10, and C=9. Are the rankings #1, #1, #3 (ties get the highest rank) or #2, #2, #3 (ties get the lowest rank)?

ya thats the problem i have is ties. so when I select the persons rank it lines up where they are in the pagination.

 

right now on my pagination script it just pulls in order if there is two users with the same experience points (for example) I'm not sure how mysql orders that if im doing order by experience DESC not sure how mysql decides who is next in line.

 

My first idea was to use

SELECT COUNT(*) FROM table WHERE points > players points

but then i was like oh wait that won't work for ties.

 

So thats the problem im having I need to pull the players exact rank as to where they would show up on my pagination script

 

 

I can do this if i used another select like select all users who have the same experience as that player and then take that informtation to figure out how many players are ahead of that player but that just seem so lame to do that.

 

 

 

I"m working on this new idea now that almost works but for some reason its off by like 4 some how haha no idea why

SET @rownum := 0;
SELECT rank, experience FROM ( 
            SELECT @rownum := @rownum + 1 AS rank, experience, id                   
             FROM game ORDER BY experience DESC                   
) as result WHERE id= 3112
Edited by Shadowing

wierd i just noticed another problem if I do this in myphpadmin

SELECT experience, id FROM game ORDER BY experience DESC

it gives me a completly differant order then my pagination script which uses

"SELECT experience,id FROM game ORDER BY experience DESC LIMIT $offset, $rowsperpage"
Edited by Shadowing

Since InnoDB has no real order im starting to think its kinda random cause i just notice if order changes on ties even on my script. Never notice this before probably cause I didnt have so many users having a tie before

Thanks Barand I"m going to try that query out. I did solve the issue just using a 2nd query which was plan B but If that query works then im going to use that instead.

 

I have another issue now though lol

Im trying to do ranks with Alliances in my game.

 

I need to do SUM(game.networth) and compare it to $users_alliance_stat for each alliance. I googled the heck out of this.

This query almost works accept it doesnt count each alliance instead returns how many members are in the first alliance.

What im trying to do is add up all the players networth that is in each alliance so I can figure out what rank a alliance is

 

 
SELECT COUNT(*), SUM(game.networth) as sum_stat FROM game  GROUP BY alliance HAVING sum_stat > $users_alliance_stat

 

 

 

an easier example that doesnt work with sql. But probably easier to understand what i'm trying to do

 

SELECT COUNT(*) FROM game WHERE SUM(game.networth)  > $users_alliance_stat

I put together a test table

CREATE TABLE test
 (
 id INT AUTO_INCREMENT PRIMARY KEY,
 alliance int(5),
 networth int(5)
 )
INSERT INTO test (alliance,networth)
VALUES(2,100),(2,150),
(3,130),(3,70),(3,80),
(4,300),(4,200),(4,100),(4,100),
(5,100),(5,220),(5,180),
(6,100),(6,220),(6,110),(6,120),(6,80)
Edited by Shadowing

Using your data

SELECT alliance, rank, total
FROM (
    SELECT alliance, 
    @row := @row+1,
    @rank := IF(totnet=@lasttot, @rank, @row) as rank,
    @lasttot := totnet as total
    FROM 
        (
        SELECT alliance, SUM(networth) as totnet
        FROM alliancetest
        GROUP BY alliance
        ORDER BY SUM(networth) DESC
        ) as tot
        JOIN (SELECT @row:=0, @lasttot:=0,@rank:=0) AS init
    ) ranks

results

+----------+------+-------+
| alliance | rank | total |
+----------+------+-------+
|        5 | 1    |  1360 |
|        4 | 2    |   700 |
|        3 | 3    |   280 |
|        2 | 4    |   250 |
+----------+------+-------+
Edited by Barand

Ahh thanks so much for doing that Barand i was sitting here trying to fill in my stuff on your other post in that other thread but that guy is using two differant tables

 

My SQL isnt this high in level yet :P

 

had to change the table to test instead of alliancetest but it works well. Thanks so much

 

hopefully this example will help break me into understanding sql variables and statements with subqueries. Cause i would really like to beable to free hand write sql on that level

Edited by Shadowing
  • Solution

and all i have to do is just add a WHERE clause to grab a certain alliance

 
SELECT alliance, rank, total
FROM (
    SELECT alliance,
    @row := @row+1,
    @rank := IF(totnet=@lasttot, @rank, @row) as rank,
    @lasttot := totnet as total
    FROM
        (
        SELECT alliance, SUM(networth) as totnet
        FROM test
        GROUP BY alliance
        ORDER BY SUM(networth) DESC
        ) as tot
        JOIN (SELECT @row:=0, @lasttot:=0,@rank:=0) AS init
    ) ranks WHERE alliance = 5
 

works great

Edited by Shadowing

One way is have it start the rank from where the alliance you are searching for. Only start the rank from the networth where your alliance is at all the way to rank 1.

Edited by Shadowing
This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.