我的代码是:
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);
}
输出代码如下:
$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++;
}
}
代码输出为:
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
但这是不对的!!! 。实际上,每个联盟的特拉维安只是一行静态数据,所以我的代码输出是错误的。每个联盟的正确输出必须如下:
Greatest Alliance
Alliance player Ø points
1. multii 3 8 23
2. myallianc 2 6 7
因为每个联盟必须只有一排
最佳答案
你的问题应该这样写:
SELECT
u.id userid,
u.username username,
u.alliance allyid,
SUM(v.pop ) AS totalpop,
SUM(a.Aap ) AS totalpoint,
COUNT(ua.alliance ) AS totalusers
FROM users u
INNER JOIN vdata v ON v.owner = u.userid
INNER JOIN alidata a ON a.id = u.allyid
INNER JOIN users ua ON ua.alliance = u.allyid
WHERE users.alliance > 0
GROUP BY u.id,
u.username,
u.alliance
ORDER BY u.totalpoint DESC,
u.allyid ASC ;
我在这个查询中所做的:
我再次编辑了表
JOIN
、users
、vdata
和alidata
,而不是您在问题中使用的这些相关子查询。注意:我再次加入表users
以获取那些具有users
但具有不同别名的用户。然后alliance = u.allyid
,在同一个查询中使用聚合函数。如果您希望包含那些未绑定的数据,例如那些在其他表中没有条目的用户,则可能还需要使用
GROUP BY
而不是LEFT JOIN
。更新1
直接针对MySQL测试查询,因为您使用的是WAMP。类似于以下步骤:
确保WAMP服务器正在运行:
从任务par打开phpMyAdmin:
选择正在使用的数据库:
导航到SQL选项卡:
在窗口中粘贴查询:
然后按下按钮。
更新1
请改为:
SELECT
u.id AS userid,
u.username AS username,
u.alliance AS allyid,
SUM(v.pop) AS totalpop,
SUM(a.Aap) AS totalpoint,
COUNT(ua.alliance) AS totalusers
FROM s1_users u
LEFT JOIN s1_vdata v ON v.owner = u.id
LEFT JOIN s1_alidata a ON a.id = u.alliance
LEFT JOIN s1_users ua ON ua.alliance = u.alliance
WHERE u.alliance > 0
GROUP BY u.id,
u.username,
u.alliance;
SQL Fiddle Demo
这将给你:
| USERID | USERNAME | ALLYID | TOTALPOP | TOTALPOINT | TOTALUSERS |
----------------------------------------------------------------------
| 4 | Multihunter | 1 | 18 | 0 | 3 |
| 5 | tester1 | 1 | 33 | 0 | 3 |
| 6 | tester2 | 1 | 18 | 0 | 3 |
注意:我在
INNER JOIN
表中找不到列allyid
,所以我将表s1_users
与s1_users
与列s1_alidata
合并,并将alliance
与自身与同一字段s1_users
合并。不确定这是否正确。但是你的桌子设计有一个大问题。你的桌子normalized。
例如,字段
alliance
、Tribe
、Access
和Gold
似乎是每个用户的相关属性,因此可以将它们移到新表中,如:Silver
:UsersFooProperties
,PropertyId
用户表的外键,UserId
,Tribe
,Access
,Gold
,组合键(
Silver
,userid`)。对于字段
ProertyId
、B1
、B2
和B3
,将它们移到新表中:B4
:UsersBs
,UserId
,B1
,B2
。但是,如果这些
B3
s大于3,并且此B
proeprty还有其他属性,则可以创建新表:B
:投标,
其他属性。。。
然后:
Bs
:Bes
,UsersBs
,组合键(
UserId
,BID
)。另一个大问题是这38个字段:
Userid
。。。,BID
,friend1
,…,friend19
。你必须为这样的朋友准备一张单独的桌子:
`用户朋友:
friend1wait
用户表的外键,friend19wait
,UserId
标志0或1。因为您只有一个列friend,在这个列中,您可以插入这38列的所有friend,如下所示:
UserId FriendId WaitOrNot
1 1 0
1 2 1
1 3 0
...
...
1 19 1
还应尽量避免将多个值存储为逗号分隔的字符串值,就像您在
FriendID
列中所做的那样。为它做一张新桌子如下:WaitOrNot
:FQUEST
,UsersFQUEST
。这只是一个例子,说明如何重新设计一个表
UserID
这些只是这个表中坏东西的一个例子,除了我提到的列之外,还有其他列。你也必须对其他桌子做同样的事情。有关详细信息,请参见以下内容:
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,一本关于SQL基础知识的好书。
A Simple Guide to Five Normal Forms in Relational Database Theory。
关于php - 如何输出正确的数据库行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14708544/