【问题标题】:Select filtered sums with joins MySQL and PHP通过连接 MySQL 和 PHP 选择过滤的总和
【发布时间】:2014-08-02 08:55:42
【问题描述】:

我正在开发一个投注系统,基本上有一组比赛(或游戏)。比赛总是有 2 支球队可供用户投注。

我有以下数据库结构:

匹配:

团队:

赌注:

我想要对查询执行的操作是从数据库中获取每场比赛中与每支球队相关的比赛和投注金额总和,并列出所有比赛以及与之相关的所有信息。

我的距离:

$query="SELECT 
a.*, 
SUM(b.amount) AS sumA, 
SUM(c.amount) AS sumB, 
d.name AS teamNameA, 
e.name AS teamNameB 
FROM matches AS a 
LEFT JOIN bets AS b ON(a.teamA = b.team_id AND a.id = b.match_id)
LEFT JOIN bets AS c ON(a.teamB = c.team_id AND a.id = c.match_id)
LEFT JOIN teams AS d ON(a.teamA = d.id)
LEFT JOIN teams AS e ON(a.teamB = e.id) GROUP BY id"

$result = mysql_query($query);

$resultArray = array();
while($row = mysql_fetch_assoc($result)){
    $resultArray[] = $row;
}

print_r($resultArray);
exit();

打印的内容:

Array
(
    [0] => Array
        (
            [id] => 1
            [teamA] => 1
            [teamB] => 2
            [teamNameA] => "Team 1"
            [teamNameB] => "Team 2"
            [sumA] => 400
            [sumB] => 200
        )
    [1] => Array
        (
            [id] => 1
            [teamA] => 1
            [teamB] => 2
            [teamNameA] => "Team 1"
            [teamNameB] => "Team 2"
            [sumA] => 
            [sumB] => 
        )
    [2] => Array
        (
            [id] => 1
            [teamA] => 1
            [teamB] => 2
            [teamNameA] => "Team 1"
            [teamNameB] => "Team 2"
            [sumA] => 
            [sumB] => 
        )
)

这几乎是完美的,但是第一行的“sumA”和“sumB”项中的数量是错误的。 “sumA”应该等于 200,“sumB”应该等于 100。当然它是重复求和过程。我尝试在 SUM 中使用“DISTINCT”语句,但它们消除了金额的相等值,“sumA”得到 100,“sumB”得到 50,这仍然是错误的。

【问题讨论】:

    标签: php mysql join sum


    【解决方案1】:

    我为您创建了一个解决方案,其中包括 sum(amount)、团队 ID 和团队名称。

    SELECT SUM(amount), bets.id, teams.name from bets
    INNER JOIN teams ON bets.team_id = teams.id GROUP BY teams.id;
    

    和 PHP 打印的不一样,但是我觉得它更有用。

    你不妨看看我写的这个 SQLFiddle。

    祝你好运。

    http://sqlfiddle.com/#!2/7ffc6/17

    【讨论】:

    • 谢谢Linial,但我必须通过比赛而不是投注来关联它,因为我想列出所有比赛并在列表中关联这些信息。但我很感激你的提示。
    • 此外,我还有其他与比赛相关的信息,我必须将这些信息包含在我未发布的其他联接中,以使问题的中心更加清晰
    • SKRocks 的子查询解决方案符合该提议。我用他的提示构建了实际的解决方案并将其发布在下面。谢谢!
    【解决方案2】:

    试试这个 sql

    SELECT  A.id as match_id, A.teamA as teamA, A.teamB as teamB, 
            (SELECT B.name FROM teams B WHERE B.id=A.teamA LIMIT 1) AS teamNameA, 
            (SELECT C.name FROM teams C WHERE C.id=A.teamB LIMIT 1) AS teamNameB, 
            (SELECT sum(D.amount) FROM bets D WHERE D.match_id=A.id AND D.team_id=A.teamA) as sumA , 
            (SELECT sum(E.amount) FROM bets E WHERE E.match_id=A.id AND E.team_id=A.teamB) as sumB 
    FROM `matches` A
    

    这太长了,需要一些时间来执行,但你会根据你的选择得到输出

    【讨论】:

    • 谢谢你!我已经尝试了 2 天。哈哈。我还维护了团队表 SELECT 的 LEFT JOIN 以提高性能,并仅用您的子查询替换了 bets 表的 SELECT。我将发布解决方案。再次感谢您!
    【解决方案3】:

    使用@SKRocks 的提示,我终于找到了正确的解决方案,将 bets 表的 LEFT JOIN 替换为子查询如下:

    $query="SELECT 
    a.*, 
    (SELECT sum(D.ammount) FROM bets AS D WHERE D.match_id=a.id AND D.team_id=a.teamA) AS sumA, 
    (SELECT sum(E.ammount) FROM bets AS E WHERE E.match_id=a.id AND E.team_id=a.teamB) AS sumB, 
    d.name AS teamNameA, 
    e.name AS teamNameB 
    FROM matches AS a 
    LEFT JOIN teams AS d ON(a.teamA = d.id)
    LEFT JOIN teams AS e ON(a.teamB = e.id) GROUP BY id";
    

    现在我得到了正确的结果并保持了 LEFT JOINS 以提高性能。我选择这个答案作为最终解决方案,因为它是我实际使用的。但是你给了我正确的提示来构建这个解决方案。

    【讨论】:

      猜你喜欢
      • 2018-09-15
      • 1970-01-01
      • 2014-08-07
      • 2012-01-22
      • 1970-01-01
      • 1970-01-01
      • 2013-12-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多