2

I have done up a query builder using join with the following setup:

My Tables

Table users

user_id | username | email          
1       | userA    | userA@email.com
2       | userB    | userB@gmail.com
                                    
                                    

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

This is my current code :

Controller

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);
        
        }
    }

Model:

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();

View

<?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'];

    }
?>

Right now I am getting many wierd duplicated data:

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

I want the result display to show like this :

  1. Display the username once
  2. Display all the game that have added to the add_game table once
  3. Display all the ign according to the game added once
  4. Display all the team that have added to the teams table once

I have totally no clue how am I going to display my results without getting duplicates. Also, what or how do I need to do if I have a few more tables after that?

Vickel
  • 7,879
  • 6
  • 35
  • 56
Dr3am3rz
  • 523
  • 1
  • 13
  • 41
  • how do you expect this output? you have a table team, but in your query you use table team_list, you don't have test3@test.com in your email column of the table users. please tidy up your question. Further: if you could explain the expected output in words would be great, just to make sure what the logic of the needed output is. Thanks – Vickel Aug 30 '20 at 21:02
  • @Vickel Apologize for the confusion. I have updated my question and have tried my best to explain in words for my expected output. Thank you! – Dr3am3rz Aug 31 '20 at 02:12

1 Answers1

3

If you perform the correct joins, you'll get the output you expect:

following your description, you start with selecting from table users, then join add_game table on it, next you join game table on add_game and last you join table teams again on add_game.

the query looks like:

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

see it in action in this sqlfiddle

the outcome is:

user_id username email game_id user_id ign acc_id game_id game_name team_id game_id leader_user_id
1   userA   userA@email.com     1   1   ignA    accA    1   gameA   5   1   1
1   userA   userA@email.com     1   1   ignA    accA    1   gameA   6   1   1
1   userA   userA@email.com     2   1   ignB    accB    2   gameB   7   2   1
1   userA   userA@email.com     2   1   ignB    accB    2   gameB   8   2   1

this query can be built with Codeigniter:

$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)

P.S.: I'm using table aliases t1, t2, etc.., which comes in handy, if table names become quite long/descriptive. It makes not only for better visibility but also means less type-work.

here is a good explanation how JOIN works: A Visual Explanation of SQL Joins

Vickel
  • 7,879
  • 6
  • 35
  • 56
  • Hi Vickel, thank you very much for your help! It's working now for me but I will still need to confirm again after I have join a few more extra tables. Would you be able to explain to me how the query you showed me works? I realized that the difference in our queries is I joined my teams table using leader_user_id = user_id whereas yours is game_id = game_id. I can't seem to understand the explanation found on the internet. – Dr3am3rz Sep 03 '20 at 08:00
  • I just followed the requirements you described. Anyway, if you look at the table structure of games and add_game, it's only logical that those need to be joined on `t4.game_id= t2.game_id` as one is an extension of the other. Before that I joined games and users on user_id. This is a good read, the learn about joins: [A Visual Explanation of SQL Joins](https://blog.codinghorror.com/a-visual-explanation-of-sql-joins/) – Vickel Sep 03 '20 at 13:20
  • Thank you Vickel. Will take a look at that. =D – Dr3am3rz Sep 03 '20 at 22:03
  • that blog is from Jeff Atwood, one of the founding fathers of this platform...user#1: https://stackoverflow.com/users/1/jeff-atwood – Vickel Sep 03 '20 at 23:17
  • I see, nice! I will try my best to understand – Dr3am3rz Sep 04 '20 at 05:54
  • @Vickel do you kindly mean tha in Codeigniter 4 the alias does OMIT the AS keyword? Do you mean that $this->db->table('users t1') aliases t1 to users? Thank you for confirming - I aks because when it is time to join two tables where two columns do have the same name in both the tables (tables 'user' and 'dept' with both having clumns 'id' and 'name'). I think it is matter of MySQL aliases, how and where do you kindly place the alias statements? And hopefully the join. Mean using the model class approach, so exactly as in this thread with $model = new CommentsModel(); approach. Thank you – Robert Jan 17 '21 at 14:08
  • @Vickel P.S. I mean that the joins I tried until now, are missing the id and the name of the users table. The join result does have all the columns of the two tables but 'id' and 'name' is present only once taken from the 'dept' table, while nowhere are present the 'user' 'id' and the 'user' 'name'. Thank you for hinting – Robert Jan 17 '21 at 14:11