I am trying to join multiple tables, however some rows are 'duplicating'. This is because one of the tables I am joining has more rows than the others (the 'Goals' table).
For exmaple, here are my three tables i am joining. The 'gamelog' (represents all the games played), 'teams' (representing all teams) and 'goals' (representing all goals that were scored in each game):
Gamelog
id | game_number | home_team_id | away_team_id |
---|---|---|---|
1 | 1 | 1 | 2 |
2 | 2 | 3 | 4 |
Teams
id | name |
---|---|
1 | MTL |
2 | BOS |
3 | CGY |
4 | EDM |
Goals
id | game_number_id | team_id_goal |
---|---|---|
1 | 1 | 2 |
2 | 1 | 2 |
3 | 1 | 1 |
4 | 2 | 4 |
5 | 2 | 4 |
When I join 'teams' and 'gamelog', it works great. I am able to display the team name instead of the id number. And it only displays one row per game. Here is my query prior to adding the third table 'goals':
Example 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 } ?>
Result:
Game 1: MTL vs BOS
Game 2: EDM vs CGY
The problem is when I add the third table called 'goals'. As you can see there are three goals scored in game #1 between MTL (team_id = 1) and BOS(team_id = 2). And two goals scored in game #2 between CGY (team_id = 3) and EDM (team_id=4)/ When I join this, it duplicates everything in gamelog by amount of goals. So game #1 is duplicated x3, and game #2 is duplicated x2.
Here is the updated query with the third table. Changes are inside the double asterisks:
Example 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 } ?>
The end result of this would have three rows under Game #1 like so:
game 1: MTL vs BOS
game 1: MTL vs BOS
game 1: MTL vs BOS
goals in game 1: MTL scores
goals in game 1: MTL scores
goals in game 1: BOS scores
game 2: CGY vs EDM
game 2 CGY vs EDM
goals in game 2: EDM scores
goals in game 2: EDM scores
I instead want it to look like this:
game 1: MTL vs BOS
goals in game 1: MTL scores
goals in game 1: MTL scores
goals in game 1: BOS scores
game 2 CGY vs EDM
goals in game 2: EDM scores
goals in game 2: EDM scores
How can I make this possible? I want to display all the goals scored in each game from 'goals' table without duplicating anything in 'gamelog' table.
Do i need to use a GROUP BY? I tried adding that into my code but my syntax must be off. I cannot get it work. Here is what I tried:
$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
It may also have something to do with how my foreach loops are set up? Or maybe even the fact that I am using 'fetchAll'?
I even tried making two separate queries. One for the gamelog like in example A from above, and the other for the goals scored. The duplication stopped since my 'gamelog' table wasn't joined to the 'goals' table, but this just resulted in my php printing all the goals in database like so:
Game 1: MTL vs BOS
goals in game 1: MTL scores
goals in game 1: MTL scores
goals in game 1: BOS scores
goals in game 2: EDM scores
goals in game 2: EDM scores
Game 2: EDM vs CGY
goals in game 1: MTL scores
goals in game 1: MTL scores
goals in game 1: BOS scores
goals in game 2: EDM scores
goals in game 2: EDM scores
Really stumped by this. I feel like it is a small error on my end and would really appreciate any help with this :)
Edit: Here is a var_dump of my $results array. It is even showing columns i didnt even include in my SELECT query
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) } }
It is the role of SQL to store and retrieve your data. It is the role of PHP to make that data meet your presentation requirements. Don't confuse the two roles and expect SQL to do presentation.
For SQL it is expected (and correct) that SQL will give you the multiplication of rows when the tables are joined, and that on each row you will see some data repeated (such as the game name). So, your problem isn't how the tables join, it is how do you use PHP to show only the items you want to see, in the order you want to see them.
See this operating at https://phpize.online/s/eC (using 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";
}
}
result
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
equivalent using 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";
}
}
?>