Webmaster Forum


Go Back   Webmaster Forum > Web Development > Web Design Lobby > Coding Forum
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

Coding Forum Problems with your code? Let's hear about it.

   

Reply
 
LinkBack Thread Tools Display Modes
Old 06-26-2006, 10:31 PM   #1 (permalink)
Contributing Member
 
Join Date: 12-14-05
Posts: 109
iTrader: 0 / 0%
Latest Blog:
None

gnznroses is on the right pathgnznroses is on the right path
Question Sorting items by a given rating. bit of a problem...

i'm listing a set of webpages on my website, sorting them by a user-given rating. for each webpage i am storing in a database the number of votes cast, a "score" which is a total of all the ratings (ie if there are votes of 4, 4, and 5, the "Score" is 12), and an average rating (score / number of votes).

original plan was to query the database, returning the list sorted by the score. problem is this, in example:

webpage 1 has one vote of 4 stars
webpage 2 has two votes of 2 stars each

both have the same score. webpage 1 should be listed first tho because it has an average rating of 4 vs 2 for webpage 2.


i thought of a second way, sorting the results by the average rating. this creates a new problem tho:

webpage 1 has 100 votes, all 5 outta 5 stars. one person votes 1 outta 5. let's assume that gives it an average rating of 4.99 (for lack of figuring it out)
webpage 2 has only one vote of 5 outta 5.

webpage 2 is gonna get listed before webpage 1 using this system.


basically, with either method, i would have to have both a primary and a secondary sort method, in order to get correct results. ie by saying in plain terms "sort these pages by average score, with the most voted for pages having priority over less voted for" or "sort these pages by their score, with the highest average score having priority over lower rated pages". is there a way to do this? does PHP/MySQL have a way of returning results sorted by a primary key, but also by a seconday key when two primaries match?

have i even explained it well enough?

Last edited by gnznroses : 06-26-2006 at 10:35 PM.
gnznroses is offline  
Add Post to del.icio.us
Reply With Quote
Old 06-27-2006, 03:55 PM   #2 (permalink)
Potato Monster
 
Immo's Avatar
 
Join Date: 03-26-04
Location: Chester, England
Posts: 3,874
iTrader: 0 / 0%
Immo is a web professional of the highest orderImmo is a web professional of the highest orderImmo is a web professional of the highest orderImmo is a web professional of the highest orderImmo is a web professional of the highest orderImmo is a web professional of the highest orderImmo is a web professional of the highest orderImmo is a web professional of the highest orderImmo is a web professional of the highest orderImmo is a web professional of the highest orderImmo is a web professional of the highest order
Send a message via ICQ to Immo Send a message via AIM to Immo Send a message via MSN to Immo Send a message via Yahoo to Immo Send a message via Skype™ to Immo
Hi gzn

I know your pain, I have done a ratings system before and its not easy.

The best thing to do is to store all the information in the database, pulling the information out and doing the calculations in the PHP is messy. In the database you should have:

#of votes field,
total score field,
avg score field,

These are updated everytime someone rates something.


If you post the current setup of your database I can probably write the PHP and SQL to get it working.
__________________
I have become death, destroyer of worlds.
Immo is offline  
Add Post to del.icio.us
Reply With Quote
Old 06-27-2006, 05:14 PM   #3 (permalink)
Contributing Member
 
Join Date: 12-14-05
Posts: 109
iTrader: 0 / 0%
Latest Blog:
None

gnznroses is on the right pathgnznroses is on the right path
yeah, those are the values i'm storing in the database. i just dunno how to query the database and have it return the results sorted by two different keys the way i need it. the names of the databse fields are:

RatingVotes <- number of votes
RatingScore <- score total
Rated <- average

so my current query looks like this:
$query = "SELECT * FROM SitesArchive WHERE Category = '$category' ORDER BY $sort DESC LIMIT $start, $limit";

where $sort in this case is curently set to either RatingScore or Rated. depending on which of the above examples you look at and which of the problems i'm trying to solve.
gnznroses is offline  
Add Post to del.icio.us
Reply With Quote
Old 06-27-2006, 06:09 PM   #4 (permalink)
Potato Monster
 
Immo's Avatar
 
Join Date: 03-26-04
Location: Chester, England
Posts: 3,874
iTrader: 0 / 0%
Immo is a web professional of the highest orderImmo is a web professional of the highest orderImmo is a web professional of the highest orderImmo is a web professional of the highest orderImmo is a web professional of the highest orderImmo is a web professional of the highest orderImmo is a web professional of the highest orderImmo is a web professional of the highest orderImmo is a web professional of the highest orderImmo is a web professional of the highest orderImmo is a web professional of the highest order
Send a message via ICQ to Immo Send a message via AIM to Immo Send a message via MSN to Immo Send a message via Yahoo to Immo Send a message via Skype™ to Immo
Just get $sort from the url? e.g. append the links where the user can select what sort order they want with a varibale like below.

page.php?sort=average
page.php?sort=total

then change the query to

$query = "SELECT * FROM SitesArchive WHERE Category = '$category' ORDER BY " . $_GET['sort'] . " DESC LIMIT $start, $limit";


That will only work if you have register globals on though. If you dont you can still use the variable that way. You just need to grab the URL from the browser, remove everything before and including = and your sorted.

Again if you need help I can do, the top solution should work, a lot of host have register globals on so you needent worry.

Its bedtime for me so if you still have problems I will pick it up and give you a hand tomorow.
__________________
I have become death, destroyer of worlds.
Immo is offline  
Add Post to del.icio.us
Reply With Quote
Old 06-27-2006, 10:56 PM   #5 (permalink)
Contributing Member
 
Join Date: 12-14-05
Posts: 109
iTrader: 0 / 0%
Latest Blog:
None

gnznroses is on the right pathgnznroses is on the right path
oh, yeah i get $sort from the url, i just meant it's set to either RatingScore or Rated for the purposes of this example.
so yeah if you could help me with the primary problem that would be really great.
gnznroses is offline  
Add Post to del.icio.us
Reply With Quote
Old 07-02-2006, 09:34 PM   #6 (permalink)
Inactive
 
wulf2001's Avatar
 
Join Date: 08-01-05
Posts: 199
iTrader: 0 / 0%
Latest Blog:
None

wulf2001 is liked by somebodywulf2001 is liked by somebodywulf2001 is liked by somebodywulf2001 is liked by somebodywulf2001 is liked by somebody
well what if a site has 95 votes with 5/5 and another has 100 with 5/5 but and a final vote of 4/5 from the 101st person... which should go first? the number of voters is pretty close. You could try grouping the number of votes like first 20 their own cat then 40, and 60 and so on, theeen... go by rank...
wulf2001 is offline  
Add Post to del.icio.us
Reply With Quote
Old 07-02-2006, 09:41 PM   #7 (permalink)
Contributing Member
 
Join Date: 12-14-05
Posts: 109
iTrader: 0 / 0%
Latest Blog:
None

gnznroses is on the right pathgnznroses is on the right path
they would be very close, but one will be ranked slightly higher, mathmetically. i'm not really concerned with very closely rated apges, but just pages that get grouped close together despite one having for example, 100 positive votes, and another only having 2 or 3.
gnznroses is offline  
Add Post to del.icio.us
Reply With Quote
Old 07-03-2006, 08:30 PM   #8 (permalink)
Contributing Member
 
Join Date: 12-14-05
Posts: 109
iTrader: 0 / 0%
Latest Blog:
None

gnznroses is on the right pathgnznroses is on the right path
wonder what happened to Immo
gnznroses is offline  
Add Post to del.icio.us
Reply With Quote
Old 08-08-2006, 09:21 PM   #9 (permalink)
Contributing Member
 
Join Date: 12-14-05
Posts: 109
iTrader: 0 / 0%
Latest Blog:
None

gnznroses is on the right pathgnznroses is on the right path
after not messing with this site since early July i figured i should try to iron out this last kink and open the site up.
anyone have further tips for me? it'd be much appreciated.
gnznroses is offline  
Add Post to del.icio.us
Reply With Quote
Old 08-08-2006, 11:11 PM   #10 (permalink)
Inactive
 
ali_420's Avatar
 
Join Date: 06-16-06
Posts: 268
iTrader: 0 / 0%
ali_420 is on the right pathali_420 is on the right pathali_420 is on the right path
Yea, you should also add a 'visits' column to your website. Whenever someone clicks on an item to view its detail, you increment the 'visits' column for that record by one. E.g...
PHP Code:
// First get the current hits of the record in a variable $currHits. Then:
$newHits=$currHits+1;
$sql="UPDATE table SET
        hits='$newHits'
        WHERE id='$id'
"
;
mysql_query($sql) or die(mysql_error()); 
-Turn off register_globals, fast. If you don't, you'll be hacked soon and come here whining about it.

- Always use mysql_real_escape_string() on the data you get from the url, and always check to make sure that it is actually a column name before putting it in a query.

- Whats the point of showing total score? Average score will do a better job than that.
ali_420 is offline  
Add Post to del.icio.us
Reply With Quote
Old 08-09-2006, 06:50 PM   #11 (permalink)
Contributing Member
 
Join Date: 12-14-05
Posts: 109
iTrader: 0 / 0%
Latest Blog:
None

gnznroses is on the right pathgnznroses is on the right path
thanks for the tips. it does count hits actually. and i think i used the mysql_real_escape_string tho i'll double check. not heard of register_globals so i'll check that out too.

Quote:
Whats the point of showing total score? Average score will do a better job than that.
i don't show total score, i only was using that internally. i want to show average score, and in fact i do, but i still haven't figured out how to sort the pages by average score. eg a page with 1 vote of 5 stars getting listed above a site with 99 5-star votes and one 4-star vote.
gnznroses is offline  
Add Post to del.icio.us
Reply With Quote
Old 08-09-2006, 07:06 PM   #12 (permalink)
v7n Mentor
 
imaginemn's Avatar
 
Join Date: 02-18-04
Location: Minneapolis, Minnesota
Posts: 1,947
iTrader: 0 / 0%
Latest Blog:
None

imaginemn is a name known to allimaginemn is a name known to allimaginemn is a name known to allimaginemn is a name known to allimaginemn is a name known to allimaginemn is a name known to allimaginemn is a name known to allimaginemn is a name known to allimaginemn is a name known to allimaginemn is a name known to allimaginemn is a name known to all
Send a message via MSN to imaginemn Send a message via Yahoo to imaginemn Send a message via Skype™ to imaginemn
Without knowing the exact fields, do something like this. Get rid of the SELECT * and only bring back the fields you want to use/display.

SELECT AVG(rated) as rated_avg
FROM table
GROUP BY site_id
ORDER BY AVG(rated) DESC

MySQL and SQL Server can auto calculate the average for you and you also have to group the commong field like website link, site id, etc.
__________________
Need a project done? - Set Your Own Price!
Imagine Creative Services
- Design : Marketing : Multimedia : More
imaginemn is offline  
Add Post to del.icio.us
Reply With Quote
Old 08-09-2006, 07:18 PM   #13 (permalink)
Contributing Member
 
Join Date: 12-14-05
Posts: 109
iTrader: 0 / 0%
Latest Blog:
None

gnznroses is on the right pathgnznroses is on the right path
hmm, that sounds promising. not sure i quite understand, as the GROUP BY is new to me. and it's hard for me to know which words are variable names you're assuming and which are PHP reseved words. here's the database field names i'm using:

RatingVotes <- number of votes
RatingScore <- score total
Rated <- average score

would you care to rewrite the code filling those in?
is the code you posted sorting the returned results in two ways? cause what i really need is sorting it by average score, primarily, with a secondary sort of the number of votes cast.
if that makes sense. hard to put into words, tho i'm sure you get the gist of it.

Last edited by gnznroses : 08-09-2006 at 07:22 PM.
gnznroses is offline  
Add Post to del.icio.us
Reply With Quote
Old 08-09-2006, 07:30 PM   #14 (permalink)
v7n Mentor
 
imaginemn's Avatar
 
Join Date: 02-18-04
Location: Minneapolis, Minnesota
Posts: 1,947
iTrader: 0 / 0%
Latest Blog:
None

imaginemn is a name known to allimaginemn is a name known to allimaginemn is a name known to allimaginemn is a name known to allimaginemn is a name known to allimaginemn is a name known to allimaginemn is a name known to allimaginemn is a name known to allimaginemn is a name known to allimaginemn is a name known to allimaginemn is a name known to all
Send a message via MSN to imaginemn Send a message via Yahoo to imaginemn Send a message via Skype™ to imaginemn
Can you post a few examples of some sample data in the db?
__________________
Need a project done? - Set Your Own Price!
Imagine Creative Services
- Design : Marketing : Multimedia : More
imaginemn is offline  
Add Post to del.icio.us
Reply With Quote
Old 08-09-2006, 07:43 PM   #15 (permalink)
v7n Mentor
 
imaginemn's Avatar
 
Join Date: 02-18-04
Location: Minneapolis, Minnesota
Posts: 1,947
iTrader: 0 / 0%
Latest Blog:
None

imaginemn is a name known to allimaginemn is a name known to allimaginemn is a name known to allimaginemn is a name known to allimaginemn is a name known to allimaginemn is a name known to allimaginemn is a name known to allimaginemn is a name known to allimaginemn is a name known to allimaginemn is a name known to allimaginemn is a name known to all
Send a message via MSN to imaginemn Send a message via Yahoo to imaginemn Send a message via Skype™ to imaginemn
If the totals are already calculated then do the following:

SELECT category, rated, ratingvotes, ratingscore
FROM SitesArchive
WHERE category = '$category'
ORDER BY rated DESC, ratingvotes DESC LIMIT $start, $limit

This query will sort the highest rated (Primary) and highest number of votes (Secondary)

EDIT: modified query.
__________________
Need a project done? - Set Your Own Price!
Imagine Creative Services
- Design : Marketing : Multimedia : More

Last edited by imaginemn : 08-09-2006 at 07:47 PM.
imaginemn is offline  
Add Post to del.icio.us
Reply With Quote
Old 08-09-2006, 08:54 PM   #16 (permalink)
Inactive
 
ali_420's Avatar
 
Join Date: 06-16-06
Posts: 268
iTrader: 0 / 0%
ali_420 is on the right pathali_420 is on the right pathali_420 is on the right path
Damn, imagine beat me to it
ali_420 is offline  
Add Post to del.icio.us
Reply With Quote
Old 08-10-2006, 02:45 PM   #17 (permalink)
Contributing Member
 
Join Date: 12-14-05
Posts: 109
iTrader: 0 / 0%
Latest Blog:
None

gnznroses is on the right pathgnznroses is on the right path
awesome, awesome. thanks imagine and everyone else who gave input :thumbsup:
if you wanna see the site i'm building, it's themicropages.com
i don't think it'll be much of a success -- my plan changed completely while i was working on it -- but it's a learning experience nonetheless.
gnznroses is offline  
Add Post to del.icio.us
Reply With Quote
Old 08-10-2006, 09:37 PM   #18 (permalink)
Contributing Member
 
Join Date: 12-14-05
Posts: 109
iTrader: 0 / 0%
Latest Blog:
None

gnznroses is on the right pathgnznroses is on the right path
oh, can someone tell me the difference between this:
SELECT category, rated, ratingvotes, ratingscore FROM
and this:
SELECT * FROM

i'm guessing it's to not allow unwanted database entries to be pulled by hackers, but since the SELECT command only returns the results, which i process inside the PHP script and selectively output only certain fields, not the raw data, i don't see how a hacker could do anything with it. i do understand that i have to check any commands that output results based on user-provided input, like when i'm doing a query and returning entries based on what is in the GET variable (the url), but i sanitize those like this:

function TranslateSort($thesort){
if ($thesort == "rated"){
return "Rated";
}elseif ($thesort == "newest"){
return "DateAdded";
}elseif ($thesort == "popular"){
return "Hits";
}else{
// don't allow sorting we don't use ourselves, eg password (also prevents injection)
return '';
}
}
gnznroses is offline  
Add Post to del.icio.us
Reply With Quote
Old 08-10-2006, 09:57 PM   #19 (permalink)
v7n Mentor
 
imaginemn's Avatar
 
Join Date: 02-18-04
Location: Minneapolis, Minnesota
Posts: 1,947
iTrader: 0 / 0%
Latest Blog:
None

imaginemn is a name known to allimaginemn is a name known to allimaginemn is a name known to allimaginemn is a name known to allimaginemn is a name known to allimaginemn is a name known to allimaginemn is a name known to allimaginemn is a name known to allimaginemn is a name known to allimaginemn is a name known to allimaginemn is a name known to all
Send a message via MSN to imaginemn Send a message via Yahoo to imaginemn Send a message via Skype™ to imaginemn
Quote:
Originally Posted by gnznroses
oh, can someone tell me the difference between this:
SELECT category, rated, ratingvotes, ratingscore FROM
and this:
SELECT * FROM
Has nothing to do with hackers. It's database optimization. If you have 10 columns and only need 3 why bring back all 10 fields of data if you are not using them? It's not a big deal with a small database with minimal traffic. Get a large database with lots of traffic and you will see a performance difference.

Also, when you do a slect * the database must figure out the column names before it brings back the data. If you specify them it's slightly faster. Once again it all depends on how big the database is.

It's always good to practice optimized techniques regardless of having a big or small database.
__________________
Need a project done? - Set Your Own Price!
Imagine Creative Services
- Design : Marketing : Multimedia : More
imaginemn is offline  
Add Post to del.icio.us
Reply With Quote
Old 08-10-2006, 10:05 PM   #20 (permalink)
Contributing Member
 
Join Date: 12-14-05
Posts: 109
iTrader: 0 / 0%
Latest Blog:
None

gnznroses is on the right pathgnznroses is on the right path
ok, thanks again.

i just now got the Top Rated sorting added in and it works perfect.
gnznroses is offline  
Add Post to del.icio.us
Reply With Quote
Go Back   Webmaster Forum > Web Development > Web Design Lobby > Coding Forum

Reply



Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools