php - 如何输出正确的数据库行

标签 php mysql sql database

我的代码是:

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 ;

我在这个查询中所做的:
我再次编辑了表JOINusersvdataalidata,而不是您在问题中使用的这些相关子查询。注意:我再次加入表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_userss1_users与列s1_alidata合并,并将alliance与自身与同一字段s1_users合并。不确定这是否正确。
但是你的桌子设计有一个大问题。你的桌子normalized
例如,字段allianceTribeAccessGold似乎是每个用户的相关属性,因此可以将它们移到新表中,如:
Silver
UsersFooProperties
PropertyId用户表的外键,
UserId
Tribe
Access
Gold
组合键(Silver,userid`)。
对于字段ProertyIdB1B2B3,将它们移到新表中:
B4
UsersBs
UserId
B1
B2
但是,如果这些B3s大于3,并且此Bproeprty还有其他属性,则可以创建新表:
B
投标,
其他属性。。。
然后:
Bs
Bes
UsersBs
组合键(UserIdBID)。
另一个大问题是这38个字段:Userid。。。,BIDfriend1,…,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/

相关文章:

php - 如何解决 XAMPP 中的禁止访问问题

php - 如果 add_action 位于 WordPress 的抽象类中,如何删除_action

mysql - SQL平均年龄比较函数返回null

php - 尝试从 MySQL 中的 PHP 输出到 Div

php - include() 从终端而不是从网络运行时失败

php - 数据库显示错误 - Webmatrix

sql - 如何根据排名值从表中选择行

php - MySQL select parents 和 child all from on table

java - 连接远程数据库时出现 JDBC 错误

mysql - MySQL binary_log 中的 SELECT 查询