社区首页 >问答首页 >使用内部查询优化查询

使用内部查询优化查询
EN

Stack Overflow用户
提问于 2013-11-17 04:40:51
回答 2查看 69关注 0票数 0

我正在开发一个应用程序,它使用PHP从MySQL数据库可视化数据。这是关于战场上的原木,其中4人杀死了谁。我想用一种特定的武器按降序列出被杀的人数,再细分为显示被杀者的名单,也按降序排列。

数据库结构:

我的PHP代码将它可视化在一个表格上:

代码语言:javascript
代码运行次数:0
复制
<?php
$con = mysql_connect("localhost", "bf4", "bf4") or die(mysql_error());
mysql_select_db("bf4") or die(mysql_error());

$query = mysql_query("SELECT p.playerId AS pid, p.playerName AS name,
    COUNT(`playerkills`.`id`) AS amount FROM `playerkills`
    JOIN players p ON playerkills.playerId = p.playerId
    WHERE weaponId = 9 GROUP BY playerkills.playerId ORDER BY amount DESC;")
    or die(mysql_error());

$i = 0;
$lastamount = -1;
$offset = 0;
while ($result = mysql_fetch_object($query)) {
    if ($lastamount != $result->amount) {
        $i += 1 + $offset;
        $offset = 0;
    } else {
        $offset++;
    }
    echo "<tr><td>".$i."</td><td>".$result->name."</td><td>".$result->amount."</td></tr>";
    echo "<tr><th></th><th>Target</th><th>Kills</th></tr>";

    $query_inner = mysql_query("SELECT p.playerName AS name,
        COUNT(`playerkills`.`id`) AS amount FROM `playerkills`
        JOIN players p ON playerkills.targetId = p.playerId 
        HERE weaponId = 9 AND playerkills.playerId = '{$result->pid}'
        GROUP BY playerkills.targetId ORDER BY amount DESC;");

    while ($result_inner = mysql_fetch_object($query_inner)) {
        echo "<tr><td></td><td>".$result_inner->name."</td><td>".$result_inner->amount."</td></tr>";
    }
    $lastamount = $result->amount;
}
mysql_close($con) or die(mysql_error());
?>

但是现在出现了额外的需求,这可能会使它变得更有趣:它应该只显示细分的数据(内部查询),如果网站用户要求它(通过单击列来指示,我稍后将在Javascript中实现)。现在有办法进一步优化查询吗?

最后一个示例是运行在已填充数据库上的代码:

我希望这个问题是正式的,如果你还有问题,那么我会相应地更新这个帖子。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-11-17 04:51:36

在循环中查询数据库并不好,这样就创建了太多的查询。对于具有不同分组的两个查询,可以获得相同的结果。这两个查询中的每一个都应该使用weapons表和players表来连接playerkills表。

通过将第一个查询按playerId分组,您将得到该播放器的总死数。然后,通过将第二个查询按playerId分组,targetId将为每个目标玩家提供死亡。

例如(未测试),

query1 -每个玩家的总结果

代码语言:javascript
代码运行次数:0
复制
SELECT p.playerId AS pid, p.playerName AS player, COUNT(*) AS kills
FROM playerkills pk
JOIN players p ON p.playerId = pk.playerId
WHERE weaponId = 9 
GROUP BY p.playerId,p.playerName ORDER BY kills DESC;

query2 -目标的详细结果

代码语言:javascript
代码运行次数:0
复制
SELECT p2.playerName AS target, COUNT(*) AS kills 
FROM playerkills pk
JOIN players p ON p.playerId = pk.playerId
JOIN players p2 ON p2.playerId = pk.targetId
WHERE weaponId = 9
GROUP BY p.playerId,p2.playerId,p2.playerName ORDER BY p.playerId, kills DESC;

只有当用户要求获得详细信息时,才能调用第二个查询,正如您所指出的,在这种情况下,您可以在AND p.playerId= $pid子句之后添加类似where的内容。在这种情况下,p.playerId在order by中并不是必需的,因为您将只获得特定玩家的结果,并且只需迭代它们。

票数 1
EN

Stack Overflow用户

发布于 2013-11-17 04:54:18

这个问题的确切答案将是很长的。

我建议您尝试使用"WITH汇总“修饰符。

With汇总肯定会优化sql侧作业,但在php端需要一些技巧。您应该将结果放在一个JSON对象中,然后使用静态创建它们的javascript整数管理html表。

如果有太多的数据管理javascript上的结果,那么您应该改变方法。

您首先需要一个PHP页面tha为您生成详细信息( webservice,称为GetDetails.php?someParams)。然后,您的主页应该只执行外部查询,并在每一行上放置一个链接以进行扩展。展开它意味着调用一个将查询GetDetails.php的AJAX脚本?并通过DOM在表中添加新行。

希望这能有所帮助

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20030767

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档