Codeigniter 4 Query Builder verknüpft 2 oder mehr Tabellen ohne doppeltes Ergebnis

Aug 31 2020

Ich habe einen Abfrage-Generator mit Join mit dem folgenden Setup erstellt:

Meine Tische

Table users

user_id | username | email          
1       | userA    | [email protected]
2       | userB    | [email protected]
                                    
                                    

Table teams
team_id | game_id | leader_user_id
5       | 1       | 1
6       | 1       | 1
7       | 2       | 1
8       | 2       | 1   

Table games
game_id | game_name
1       | gameA
2       | gameB
3       | gameC
 

Table add_game

game_id | user_id | ign  | acc_id
1       | 1       | ignA | accA
2       | 1       | ignB | accB
3       | 1       | ignC | accC

Dies ist mein aktueller Code:

Regler

public function profile()
    {
        $data = []; $db = db_connect();
            $model = new ProfileModel($db);
            $data['profile'] = $model->getProfile();
            
            echo view('templates/header', $data); echo view('account/profile', $data);
            echo view('templates/footer', $data);
        
        }
    }

Modell:

return $this->db->table('users')
                        ->join('add_game', 'add_game.user_id = users.user_id')
                        ->join('teams', 'teams.leader_user_id = users.user_id')
                        ->join('games', 'games.game_id = add_game.game_id')
                        ->where('users.user_id', $user_id)
                        //->groupBy('users.user_id')
                        //->distinct('users.user_id')
                        //->select(("GROUP_CONCAT(game_id, ign, acc_id) AS userdata"))
                        ->get()
                        ->getResultArray();

Aussicht

<?php

    $my_id = 0;
    foreach($profile as $row){

        if($my_id != $row['user_id']){
?>
            <div><?=$row['username']?></div> <!--data from table user--> <div><?=$row['game_name']?></div> <!--data from table add_game-->
            <div><?=$row['ign']?></div> <div><?=$row['acc_id']?></div>
            <div><?=$row['team_id']?></div> <?php } else { ?> <div><?=$row['game_name']?></div>
            <div><?=$row['ign']?></div> <!--only data from table add_game--> <div><?=$row['acc_id']?></div>
            <div><?=$row['team_id']?></div> <?php } $my_id = $row['user_id'];

    }
?>

Im Moment bekomme ich viele seltsame doppelte Daten:

userA
gameA
ignA
accA
5

gameB
ignB
accB
5

gameC
ignC
accC
5

gameA
ignA
accA
6

gameB
ignB
accB
6

gameC
ignC
accC
6

gameA
ignA
accA
7

gameB
ignB
accB
7

gameC
ignC
accC
7

gameA
ignA
accA
8

gamneB
ignB
accB
8

gameC
ignC
accC
8

Ich möchte, dass die Ergebnisanzeige folgendermaßen angezeigt wird:

  1. Zeigen Sie den Benutzernamen einmal an
  2. Zeigt alle Spiele an, die einmal zur Tabelle add_game hinzugefügt wurden
  3. Zeigen Sie alle Zündgeräte entsprechend dem einmal hinzugefügten Spiel an
  4. Zeigen Sie alle Teams an, die einmal zur Teamtabelle hinzugefügt wurden

Ich habe überhaupt keine Ahnung, wie ich meine Ergebnisse anzeigen soll, ohne Duplikate zu erhalten. Was oder wie muss ich tun, wenn ich danach noch ein paar Tabellen habe?

Antworten

3 Vickel Aug 31 2020 at 22:28

Wenn Sie die richtigen Verknüpfungen ausführen, erhalten Sie die erwartete Ausgabe:

Nach Ihrer Beschreibung beginnen Sie mit der Auswahl aus Tabellenbenutzern, verbinden sich dann mit der Tabelle add_game, schließen sich als nächstes der Spieltabelle mit add_game an und zuletzt verbinden Sie die Tabellenteams erneut mit add_game.

Die Abfrage sieht folgendermaßen aus:

SELECT *
from users t1
join add_game t2
on t2.user_id = t1.user_id
join games t3
on t3.game_id=t2.game_id
join teams t4
on t4.game_id=t2.game_id
where t1.user_id=1

Sehen Sie es in Aktion in dieser SQLfiddle

Das Ergebnis ist:

user_id username email game_id user_id ign acc_id game_id game_name team_id game_id leader_user_id
1   userA   [email protected]     1   1   ignA    accA    1   gameA   5   1   1
1   userA   [email protected]     1   1   ignA    accA    1   gameA   6   1   1
1   userA   [email protected]     2   1   ignB    accB    2   gameB   7   2   1
1   userA   [email protected]     2   1   ignB    accB    2   gameB   8   2   1

Diese Abfrage kann mit Codeigniter erstellt werden:

$user_id=1; $this->db->table('users t1')
->join('add_game t2', 't2.user_id = t1.user_id')
->join('games t3', 't3.game_id = t2.game_id')
->join('teams t4', 't4.game_id= t2.game_id')
->where('t1.user_id', $user_id)

PS: Ich verwende Tabellenaliasnamen t1, t2 usw., was praktisch ist, wenn Tabellennamen ziemlich lang / beschreibend werden. Dies sorgt nicht nur für eine bessere Sichtbarkeit, sondern bedeutet auch weniger Schreibarbeit.

Hier ist eine gute Erklärung, wie JOIN funktioniert: Eine visuelle Erklärung von SQL-Joins