多重连接从其他表复制行

问题描述 投票:0回答:1

我正在尝试连接多个表,但是有些行正在“重复”。这是因为我加入的其中一个表的行数比其他表(“目标”表)多。

例如,这是我要加入的三张桌子。 'gamelog'(代表所有比赛),'teams'(代表所有球队)和'goals'(代表每场比赛的所有进球):

游戏日志

id 游戏编号 home_team_id away_team_id
1 1 1 2
2 2 3 4

团队

id 姓名
1 母语
2 老板
3 CGY
4 电音

目标

id 游戏编号_id team_id_goal
1 1 2
2 1 2
3 1 1
4 2 4
5 2 4

当我加入“团队”和“游戏日志”时,效果很好。我能够显示团队名称而不是 ID 号。而且它每场比赛只显示一行。这是我在添加第三个表“目标”之前的查询:

例子A

$sql = "SELECT gamelog.game_number, gamelog.home_team_id, gamelog.away_team_id, 
t1.name AS hometeam, t2.name AS awayteam";

FROM gamelog
JOIN teams AS t1 ON gamelog.home_team_id=t1.id
JOIN teams AS t2 ON gamelog.away_team_id=t2.id

$statement = $pdo->query($sql);
$results = $statement->fetchAll();

<?php foreach($results as $result) { ?>
  Game Number: <?=$result['game_number'];?>
   
    <?=$result['hometeam'].' VERSUS '.$result['awayteam']; ?>
    
    
    <?php } ?>

结果:

第一局:MTL vs BOS

第二场比赛:EDM vs CGY

问题是当我添加名为“目标”的第三个表时。如您所见,在第 1 场比赛中,MTL (team_id = 1) 和 BOS(team_id = 2) 之间进了三个球。在 CGY (team_id = 3) 和 EDM (team_id = 4) 之间的第 2 场比赛中有两个进球/当我加入这个时,它会按进球数量复制游戏日志中的所有内容。所以游戏 #1 被复制 x3,游戏 #2 被复制 x2.

这是对第三张表的更新查询。更改在双星号内:

例子B

$sql = "SELECT gamelog.game_number, gamelog.home_team_id, gamelog.away_team_id, 
t1.name AS hometeam, t2.name AS awayteam,
**goals.game_number_id**";

FROM gamelog
JOIN teams AS t1 ON gamelog.home_team_id=t1.id
JOIN teams AS t2 ON gamelog.away_team_id=t2.id
**JOIN goals ON gamelog.game_number = goals.game_number_id**

$statement = $pdo->query($sql);
$results = $statement->fetchAll();



 <?php foreach($results as $result) { ?>
        Game Number: <?=$result['game_number'];?>
        <br>
        <?=$result['hometeam'].' VERSUS '.$result['awayteam']; ?>
        <br>
        Which team scored the goals: <?=$result['team_id_goal']; ?>
        <br>
        
        <?php } ?>

这的最终结果将在游戏 #1 下有三行,如下所示:

第一局:MTL vs BOS

第一局:MTL vs BOS

第一局:MTL vs BOS

第一场比赛的目标:MTL得分

第一场比赛的目标:MTL得分

第一局进球:BOS得分

第二局:CGY vs EDM

游戏 2 CGY vs EDM

第二场比赛的目标:EDM得分

第二场比赛的目标:EDM得分

我反而希望它看起来像这样:

第一局:MTL vs BOS

第一场比赛的目标:MTL得分

第一场比赛的目标:MTL得分

第一局进球:BOS得分

游戏 2 CGY vs EDM

第二场比赛的目标:EDM得分

第二场比赛的目标:EDM得分

我怎样才能使这成为可能?我想从“目标”表中显示每场比赛中的所有进球,而不复制“游戏日志”表中的任何内容。

我需要使用 GROUP BY 吗?我尝试将其添加到我的代码中,但我的语法必须关闭。我无法让它工作。这是我尝试过的:

 $sql = "SELECT gamelog.game_number, gamelog.home_team_id, gamelog.away_team_id, 
    t1.name AS hometeam, t2.name AS awayteam,
    goals.game_number_id,
    COUNT(*)";
    
FROM gamelog
JOIN teams AS t1 ON gamelog.home_team_id=t1.id
JOIN teams AS t2 ON gamelog.away_team_id=t2.id
JOIN goals ON gamelog.game_number = goals.game_number_id
GROUP BY gamelog.game_number

这也可能与我的 foreach 循环的设置方式有关?或者甚至是我正在使用“fetchAll”的事实?

我什至尝试进行两个单独的查询。一个是游戏日志,如上面的示例A,另一个是进球数。由于我的“游戏日志”表没有加入“目标”表,所以复制停止了,但这只是导致我的 php 打印数据库中的所有目标,如下所示:

第一局:MTL vs BOS

第一场比赛的目标:MTL得分

第一场比赛的目标:MTL得分

第一局进球:BOS得分

第二场比赛的目标:EDM得分

第二场比赛的目标:EDM得分

第二场比赛:EDM vs CGY

第一场比赛的目标:MTL得分

第一场比赛的目标:MTL得分

第一局进球:BOS得分

第二场比赛的目标:EDM得分

第二场比赛的目标:EDM得分

真的被这个难住了。我觉得这是我的一个小错误,非常感谢对此的任何帮助:)

编辑:这是我的 $results 数组的 var_dump。它甚至显示了我什至没有包含在我的 SELECT 查询中的列

array(8) { [0]=> array(11) { ["game_number"]=> int(1) ["home_team_id"]=> int(1) ["away_team_id"]=> int(2) ["home_score"]=> int(2) ["away_score"]=> int(1) ["hometeam"]=> string(3) "MTL" ["awayteam"]=> string(3) "BOS" ["homelogo"]=> string(12) "habs-svg.svg" ["awaylogo"]=> string(14) "bruins-svg.svg" ["game_number_id"]=> int(1) ["team_id_goal"]=> int(1) } [1]=> array(11) { ["game_number"]=> int(1) ["home_team_id"]=> int(1) ["away_team_id"]=> int(2) ["home_score"]=> int(2) ["away_score"]=> int(1) ["hometeam"]=> string(3) "MTL" ["awayteam"]=> string(3) "BOS" ["homelogo"]=> string(12) "habs-svg.svg" ["awaylogo"]=> string(14) "bruins-svg.svg" ["game_number_id"]=> int(1) ["team_id_goal"]=> int(1) } [2]=> array(11) { ["game_number"]=> int(1) ["home_team_id"]=> int(1) ["away_team_id"]=> int(2) ["home_score"]=> int(2) ["away_score"]=> int(1) ["hometeam"]=> string(3) "MTL" ["awayteam"]=> string(3) "BOS" ["homelogo"]=> string(12) "habs-svg.svg" ["awaylogo"]=> string(14) "bruins-svg.svg" ["game_number_id"]=> int(1) ["team_id_goal"]=> int(2) } [3]=> array(11) { ["game_number"]=> int(2) ["home_team_id"]=> int(2) ["away_team_id"]=> int(1) ["home_score"]=> int(3) ["away_score"]=> int(2) ["hometeam"]=> string(3) "BOS" ["awayteam"]=> string(3) "MTL" ["homelogo"]=> string(14) "bruins-svg.svg" ["awaylogo"]=> string(12) "habs-svg.svg" ["game_number_id"]=> int(2) ["team_id_goal"]=> int(2) } [4]=> array(11) { ["game_number"]=> int(2) ["home_team_id"]=> int(2) ["away_team_id"]=> int(1) ["home_score"]=> int(3) ["away_score"]=> int(2) ["hometeam"]=> string(3) "BOS" ["awayteam"]=> string(3) "MTL" ["homelogo"]=> string(14) "bruins-svg.svg" ["awaylogo"]=> string(12) "habs-svg.svg" ["game_number_id"]=> int(2) ["team_id_goal"]=> int(2) } [5]=> array(11) { ["game_number"]=> int(2) ["home_team_id"]=> int(2) ["away_team_id"]=> int(1) ["home_score"]=> int(3) ["away_score"]=> int(2) ["hometeam"]=> string(3) "BOS" ["awayteam"]=> string(3) "MTL" ["homelogo"]=> string(14) "bruins-svg.svg" ["awaylogo"]=> string(12) "habs-svg.svg" ["game_number_id"]=> int(2) ["team_id_goal"]=> int(2) } [6]=> array(11) { ["game_number"]=> int(2) ["home_team_id"]=> int(2) ["away_team_id"]=> int(1) ["home_score"]=> int(3) ["away_score"]=> int(2) ["hometeam"]=> string(3) "BOS" ["awayteam"]=> string(3) "MTL" ["homelogo"]=> string(14) "bruins-svg.svg" ["awaylogo"]=> string(12) "habs-svg.svg" ["game_number_id"]=> int(2) ["team_id_goal"]=> int(1) } [7]=> array(11) { ["game_number"]=> int(2) ["home_team_id"]=> int(2) ["away_team_id"]=> int(1) ["home_score"]=> int(3) ["away_score"]=> int(2) ["hometeam"]=> string(3) "BOS" ["awayteam"]=> string(3) "MTL" ["homelogo"]=> string(14) "bruins-svg.svg" ["awaylogo"]=> string(12) "habs-svg.svg" ["game_number_id"]=> int(2) ["team_id_goal"]=> int(1) } }
php mysql join duplicates row
1个回答
0
投票

存储和检索数据是 SQL 的作用。 PHP 的作用是使该数据满足您的演示要求。不要混淆这两个角色并期望 SQL 进行表示。

对于 SQL,预计(并且正确)SQL 会在连接表时为您提供行的乘法,并且在每一行上您会看到一些重复的数据(例如游戏名称)。所以,你的问题不是表如何连接,而是你如何使用 PHP 以你想看到的顺序只显示你想看的项目。

https://phpize.online/s/eC(使用 pdo)上查看此操作

<?php
// Using PDO
$sql = "SELECT g.game_number, ht.name AS home_team, at.name AS away_team
        FROM Gamelog g
        JOIN Teams ht ON g.home_team_id = ht.id
        JOIN Teams at ON g.away_team_id = at.id";
$stmt = $pdo->prepare($sql);
$stmt->execute();
$result = $stmt->fetchAll();

foreach ($result as $row) {
    echo "game " . $row["game_number"] . ": " . $row["home_team"] . " vs " . $row["away_team"] . "\n";

    $sql2 = "SELECT t.name AS team_name
             FROM Goals g
             JOIN Teams t ON g.team_id_goal = t.id
             WHERE g.game_number_id = :game_number";
    $stmt2 = $pdo->prepare($sql2);
    $stmt2->execute(['game_number' => $row["game_number"]]);
    $result2 = $stmt2->fetchAll();

    foreach ($result2 as $row2) {
        echo "goals in game " . $row["game_number"] . ": " . $row2["team_name"] . " scores\n";
    }
}

结果

game 1: MTL vs BOS
goals in game 1: BOS scores
goals in game 1: BOS scores
goals in game 1: MTL scores
game 2: CGY vs EDM
goals in game 2: EDM scores
goals in game 2: EDM scores

相当于使用 MySQLi

// Using MySQLi
$sql = "SELECT g.game_number, ht.name AS home_team, at.name AS away_team
        FROM Gamelog g
        JOIN Teams ht ON g.home_team_id = ht.id
        JOIN Teams at ON g.away_team_id = at.id";
$result = $mysqli->query($sql);

while ($row = $result->fetch_assoc()) {
    echo "game " . $row["game_number"] . ": " . $row["home_team"] . " vs " . $row["away_team"] . "\n";

    $sql2 = "SELECT t.name AS team_name
             FROM Goals g
             JOIN Teams t ON g.team_id_goal = t.id
             WHERE g.game_number_id = ?";
    $stmt2 = $mysqli->prepare($sql2);
    $stmt2->bind_param("i", $row["game_number"]);
    $stmt2->execute();
    $result2 = $stmt2->get_result();

    while ($row2 = $result2->fetch_assoc()) {
        echo "goals in game " . $row["game_number"] . ": " . $row2["team_name"] . " scores\n";
    }
}
?>

https://phpize.online/s/GC

© www.soinside.com 2019 - 2024. All rights reserved.