我正在尝试连接多个表,但是有些行正在“重复”。这是因为我加入的其中一个表的行数比其他表(“目标”表)多。
例如,这是我要加入的三张桌子。 '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) } }
存储和检索数据是 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";
}
}
?>