corsasport.co.uk
 

Corsa Sport » Message Board » Off Day » Geek Day » SQL gurus, can this be done in a single query?


New Topic

New Poll
  Subscribe | Add to Favourites

You are not logged in and may not post or reply to messages. Please log in or create a new account or mail us about fixing an existing one - register@corsasport.co.uk

There are also many more features available when you are logged in such as private messages, buddy list, location services, post search and more.


Author SQL gurus, can this be done in a single query?
xa0s
Banned

Registered: 4th Mar 08
Location: Dartford, Kent Car: Turbo'd Fabia vRS
User status: Offline
12th May 10 at 07:35   View User's Profile U2U Member Reply With Quote

So basically we have a highscores for a RPG, there's around 40,000 character records in the rscd_experience table with 18 columns for each skill. I need to obtain their overall rank for each skill (ranking the person with the most experience at #1 and the person with the least experience at the end).

code:
<?php
$skills = array("attack", "defense", "strength", "hits", "ranged", "prayer", "magic", "cooking", "woodcut", "fletching", "fishing", "firemaking", "crafting", "smithing", "mining", "herblaw", "agility", "thieving");

for($i = 0; $i < count($skills); $i++){
$rank = $db->query("SELECT `user` FROM `rscd_experience` WHERE `exp_" . $skills[$i] . "` > 0");
$rank = $db->num_rows($rank) + 1;
echo ucwords($skills[$i]) . " Rank: " . number_format($getRank) . "<br />";
}
?>


I've heard it can be done by setting a @var within the query and then looping through, I've managed to do it with one skill but it involves setting the @var before the query which fucks up when using PHP.

PS. The above isn't my code. I left this feature out as it's tacky and I'd sooner not have a feature than have the above taking 4 seconds to load a page...

Major props if anyone is able to do this...
James
Member

Registered: 1st Jun 02
Location: Surrey
User status: Offline
12th May 10 at 09:17   View User's Profile U2U Member Reply With Quote

So each person has one row in the table?

And each row has a column for each skill, 18 in total?

And what is the final output you are trying to produce?
noshua
Member

Registered: 19th Nov 08
User status: Offline
12th May 10 at 10:42   View User's Profile U2U Member Reply With Quote

I can help with the coding but in regards with having the page taking 4 seconds to load, you could set up a job to do it once every hour and publish it to a file. It'd save a he'll of a lot of stress on your server, especially with people constantly refreshing.
Dom
Member

Registered: 13th Sep 03
User status: Offline
12th May 10 at 10:49   View User's Profile U2U Member Reply With Quote

Couldn't you self join the `rscd_experience` table (obviously use aliases)? Atleast then you'd get it down to one query.
daymoon
Premium Member

Registered: 1st Aug 08
Location: Selby, North Yorkshire
User status: Offline
12th May 10 at 11:06   View Garage View User's Profile U2U Member Reply With Quote

Runescape
xa0s
Banned

Registered: 4th Mar 08
Location: Dartford, Kent Car: Turbo'd Fabia vRS
User status: Offline
12th May 10 at 11:13   View User's Profile U2U Member Reply With Quote

quote:
Originally posted by Dom
Couldn't you self join the `rscd_experience` table (obviously use aliases)? Atleast then you'd get it down to one query.

Give me an example? Never heard of a self join.

quote:
Originally posted by noshua
I can help with the coding but in regards with having the page taking 4 seconds to load, you could set up a job to do it once every hour and publish it to a file. It'd save a he'll of a lot of stress on your server, especially with people constantly refreshing.

I know that and probably will, but I really want to fix this. I have turned into a SQL head lately and it annoys me that I'm having difficulties with it.

quote:
Originally posted by James
So each person has one row in the table?

And each row has a column for each skill, 18 in total?

And what is the final output you are trying to produce?

Correct.

Output should be like:

user | exp_attack | rank_attack | exp_strength | rank_strength | exp_defense | rank_defense | exp_hits | rank_hits ...
xa0s | 130349385 | 3 | 10000 | 1394 | 0 | 35093 | 3000000 | 392t


I need to search by user.
Dom
Member

Registered: 13th Sep 03
User status: Offline
12th May 10 at 12:40   View User's Profile U2U Member Reply With Quote

Google MySQL Self Join, this might also help (re-reading your post though i don't think it will) - http://www.devshed.com/c/a/MySQL/MySQL-Table-Joins/4/

Are you trying to get a single user details (skills)? Why aren't you just doing a "SELECT * FROM `rscd_experience` WHERE `user_id == '10'" etc then grabbing each column? You then just search by `user_id` (or name or what ever) and ORDER BY what ever skill you want.
If you want all users then get rid of the WHERE and just ORDER BY.

It's just that query seems to grab all users per skill and echos them out, which doesn't make sense if you're trying pull users from the table and rank them.

I'm most likely way off the mark with this all though!
xa0s
Banned

Registered: 4th Mar 08
Location: Dartford, Kent Car: Turbo'd Fabia vRS
User status: Offline
12th May 10 at 12:56   View User's Profile U2U Member Reply With Quote

You are way off...
Ian
Site Administrator

Avatar

Registered: 28th Aug 99
Location: Liverpool
User status: Offline
12th May 10 at 18:18   View Garage View User's Profile U2U Member Reply With Quote

Can you post a few rows from the table and a mock-up of what you want to see.

I'll probably end up recommending that you get rid of that bloody awful string concatenation to derive your field names, but I'll gladly give it a try.
Reedy
Member

Registered: 11th Apr 04
Location: Hammersmith
User status: Offline
12th May 10 at 19:41   View User's Profile U2U Member Reply With Quote

you could have a temp table (or a normal one) for every column which contains just the username and rank.
INSERT INTO skill_name_rank_table VALUES
SELECT username from TABLE ORDER BY skill_name ASC

Would this not work?
Obviously you would have to do it 18 times, but it would be fairly easy to maintain/update and selects should be fairly fast.

Paul_J
Member

Registered: 6th Jun 02
Location: London
User status: Offline
12th May 10 at 20:07   View User's Profile U2U Member Reply With Quote

Right, I think I've got what you need... almost... 2 secs.
Paul_J
Member

Registered: 6th Jun 02
Location: London
User status: Offline
12th May 10 at 20:21   View User's Profile U2U Member Reply With Quote

Ok... I just mocked up a simple example on MS SQL - So forgive me if this doesn't work in MySQL.

Basically, I would do a select like the following (but obviously continuing it for all your columns)... and load the data into a datatable.



I would then use that datatable to pull out any statistics I need... e.g. query the datatable for a user's overall statistics, or query it for the top 1 ranked player in exp_strength... or give me a list the top 100 players with exp_hits or whatever...

e.g. a query on the above datatable where user = 'tommy' would give
user | exp_attack | rank attack | exp_hits | rank_hits | exp_defense | rank_defense
tommy | 26 | ranked 1st | 26 | ranked 3rd | 25 | ranked 2nd

Up to you though, but that's how i'd do it.

[Edited on 12-05-2010 by Paul_J]
Paul_J
Member

Registered: 6th Jun 02
Location: London
User status: Offline
12th May 10 at 20:33   View User's Profile U2U Member Reply With Quote

p.s. I think a lot of people here have mis understood his situation and what he wants.

He doesn't have a 'rank' he needs to figure out what each person's rank is, based on their experience (e.g. the person with the most experience is highest rank (either 1 for first, or top number (just change the order desc to asc)).

Therefore it needs to figure out, per skill, where that user is out of all the records and return the result as a 'rank' number.

I took the assumption in the above that 'rank' would be 1 for the person with the highest exp in each skill. e.g. '1st in that skill'
Ian
Site Administrator

Avatar

Registered: 28th Aug 99
Location: Liverpool
User status: Offline
13th May 10 at 16:21   View Garage View User's Profile U2U Member Reply With Quote

quote:
Originally posted by Ian
Can you post a few rows from the table and a mock-up of what you want to see.
Paul_J
Member

Registered: 6th Jun 02
Location: London
User status: Offline
14th May 10 at 18:33   View User's Profile U2U Member Reply With Quote

good to see xaos followed this thread up with an update.

 
New Topic

New Poll

  Related Threads Author Forum Replies Views Last Post
SQL - pronounciation Sam Geek Day 31 1818
8th Jan 10 at 17:41
by Tom G
 
(my)SQL dudes Dom Geek Day 9 642
3rd May 07 at 23:50
by Dom
 
VB6 problem - strings Ian Geek Day 19 512
12th Mar 08 at 23:30
by Ian
 
PHP help again Dan Lewis Geek Day 25 1376
3rd Feb 09 at 21:26
by Dan Lewis
 
Php help? (mysql_num_rows) Whittie Geek Day 17 1521
15th Jan 10 at 14:38
by Dom
 

Corsa Sport » Message Board » Off Day » Geek Day » SQL gurus, can this be done in a single query? 29 database queries in 0.0218899 seconds