My code is this :
public function procAllianceAttRanking($limit="") {
$q = "SELECT " . TB_PREFIX . "users.id userid, " . TB_PREFIX . "users.username username, " . TB_PREFIX . "users.alliance allyid, (
SELECT SUM( " . TB_PREFIX . "vdata.pop )
FROM " . TB_PREFIX . "vdata
WHERE " . TB_PREFIX . "vdata.owner = userid
)totalpop, (
SELECT SUM( " . TB_PREFIX . "alidata.Aap )
FROM " . TB_PREFIX . "alidata
WHERE " . TB_PREFIX . "alidata.id = allyid
)totalpoint, (
SELECT COUNT( " . TB_PREFIX . "users.alliance )
FROM " . TB_PREFIX . "users
WHERE " . TB_PREFIX . "users.alliance = allyid
)totalusers
FROM " . TB_PREFIX . "users
WHERE " . TB_PREFIX . "users.alliance > 0
ORDER BY totalpoint DESC, allyid ASC $limit";
return mysql_query($q);
}
and output code is this :
$sql = $ranking->procAllianceRanking();
$query = mysql_num_rows($sql);
if($query >= 1){
while($row = mysql_fetch_array($sql)){
if($row['allyid'] == $session->alliance) {
echo "<tr class=\"hl\"><td class=\"ra fc\" >".$rank.".</td>";
}else {
echo "<tr class=\"hover\"><td class=\"ra \" >".$rank.".</td>";
}
echo "<td class=\"al \" ><a href=\"allianz.php?aid=".$row['allyid']."\">".$database->getAllianceName($row['allyid'])."</a></td>";
echo "<td class=\"pla \" >".$row['totalusers']."</td>";
echo "<td class=\"av \">".round($row['totalpop']/$row['totalusers'])."</td>";
echo "<td class=\"po lc\">".$row['totalpop']."</td></tr>";
$rank++;
}
}
And output of the codes is :
Greatest Alliance
Alliance player Ø points
1. multii 3 4 11
2. multii 3 2 6
3. multii 3 2 6
4. myallianc 2 5 5
5. myallianc 2 1 2
but this is not correct !!! . in real travian for each alliance is just one row in statics so the output of my code is wrong . the correct output for each alliance must be like :
Greatest Alliance
Alliance player Ø points
1. multii 3 8 23
2. myallianc 2 6 7
For every alliance must be only one row
Your query should be written this way:
What I have done in this query:
I
JOINed the tablesusers,vdata,alidataandusersagain instead of these correlated subqueries that you used in your question. Note that: I joined the tableusersone more times to get those users that hasalliance = u.allyidbut with a different alias. ThenGROUP BY, with aggregate functions in the same query.You might also need to use
LEFT JOINinstead ofINNER JOINin case you want to include those unmtached data, i.e those users that has no entries in the others tables for example.Update 1
To test the query against MySQL directly, and since you are using WAMP. Like in the following steps:
Update 1
Try this instead:
SQL Fiddle Demo
This will give you:
Note that: I couldn’t find a column
allyidin thes1_userstable, so I joined the tables1_userswiths1_alidatawith the columnallianceands1_userswith itself with the same fieldalliance. Not sure if this is right or not.But there is a big problem in your tables’ design. Your tables are normalized.
For instance, it seems that the fields
Tribe,Access,GoldandSilverare related attributes for each user, so you can move them to a new table something like:UsersFooProperties:PropertyId,UserIda foreign key to the users table,Tribe,Access,Gold,Silver,ProertyId, userid`).The same for the fields
B1,B2,B3andB4, move them to a new table:UsersBs:UserId,B1,B2,B3.However, if these
Bs are more than three and there are other properties for thisBproeprty, you can create a new tableBs:Bes:Then:
UsersBs:UserId,BID,Userid,BID).Another big issue is with those 38 fields:
friend1, … ,friend19,friend1wait, …,friend19wait.You have to have a separate table for those friends like this:
`UsersFriends:
UserIda foreign key to the users table,FriendID,WaitOrNota flag 0 or 1.There for you have only one column friend, in this column you can insert all the friends of these 38 columns like this:
Also try to avoid storing mutiple values as a comma separated string value, like what you did in the column
FQUEST. Make a new table for it like this:UsersFQUEST:UserID,FQUESTId.This was just an example of how you can redesign one of your table
usersthese are just a sample of bad things you have in this table, you have other columns than these that I mentioned. You have also to do the same things for other tables.For more information, see these:
Join (SQL)From Wikipedia.
Visual Representation of SQL Joins.
Another Visual Explanation of SQL Joins.
SQL Queries for Mere Mortals(R): A Hands-On Guide to Data Manipulation in SQL, a great book for SQL Basics.
A Simple Guide to Five Normal Forms in Relational Database Theory.