Joining multiple tables in laravel query builder results in duplication - php

I'm trying to use Laravel Query Builder to join 2 tables.
Here's my query for joining 2 tables
$instructors = DB::table('instructors')
->join('instructor_courses', 'instructors.id', '=','instructor_courses.instructor_id')
->where('instructor_courses.course_id', $schedule->course_id)
->where('instructor_courses.position', 'Instructor')
->whereNull('instructor_courses.deleted_at')
->whereNull('instructors.deleted_at')
->get();
The code let me join the table properly however this results to multiple duplication. Take a look at the result passed in select tag
Here's the schema I have
Instructor Table
Instructor Courses Table
Basically what I want to achieve is to display a record without duplication. Is there a better approach in joining multiple table like this one? Thank you

You should use groupBy for instructors.id
$instructors = DB::table('instructors')
->join('instructor_courses', 'instructors.id', '=','instructor_courses.instructor_id')
->where('instructor_courses.course_id', $schedule->course_id)
->where('instructor_courses.position', 'Instructor')
->whereNull('instructor_courses.deleted_at')
->whereNull('instructors.deleted_at')
->groupBy('instructors.id') //add a line
->get();

Try to use the ->distinct() function in laravel to prevent duplicates in selecting data.
$instructors = DB::table('instructors')
->join('instructor_courses', 'instructors.id', '=','instructor_courses.instructor_id')
->where('instructor_courses.course_id', $schedule->course_id)
->where('instructor_courses.position', 'Instructor')
->whereNull('instructor_courses.deleted_at')
->whereNull('instructors.deleted_at')
->groupBy('instructors.id')
->distinct()
->get();

Related

Select the distinct latest records based on their creation date

How can I select, preferably using eloquent laravel's query builder, the latest distinct records from a table.
I have tried this query without success.
Products::where('depart_id', $depart_id)
->distinct("serial_number")
->latest()
->where('serial_number', ""); // get one of the distinct products
You can try this: distinct() will get the distinct 'serial_number'
Products::where('depart_id', $depart_id)
->where('serial_number', "")
->distinct();
The solution was to use
Products::where('depart_id', $depart_id)
->distinct('serial_number')
->orderBy('serial_number', 'desc')
->orderBy('created_at', 'desc')
->where('serial_number', "serial_number");
This ensured that the distinct returned only the unique latest record of each value.

Using multi where queries Laravel relationships

I have two tables (Table1, Table2).
I want to print the sum of the records whose properties match Table1 in Table2 while listing the Table1 table.
My two tables contain very large records, performance is important to me.
// Model -> relationships
public function cars()
{
return $this->hasMany('App\Models\Table2', 'list_id', 'list_id');
}
// Controller
$table1 = Table1::with('cars' => function($query){
$query->where('table2.color','=', 'table1.color')
$query->where('table2.year','=', 'table1.year')
}])
->get();
I'm adding the sample database pictures:
Thank you.
First, add below use statement to the top of your controller:
use DB;
Now, If you only want to get the records amount, you can do this:
$amount = DB::table('table1')
->join('table2', function($join){
$join->on('table1.color', '=', 'table2.color');
$join->on('table1.year', '=', 'table2.year');
})->count();
But if you want to get the list of the table1 records, you can change the query a bit like below:
$records = DB::table('table1')
->select('table1.*')
->join('table2', function($join){
$join->on('table1.color', '=', 'table2.color');
$join->on('table1.year', '=', 'table2.year');
})->count();
Please follow Laravel's official guide on this topic:
https://laravel.com/docs/8.x/queries#advanced-join-clauses
Use join to merge the two tables read more about join here https://www.w3schools.com/sql/sql_join.asp

Using Laravel's WhereIn to search multiple tables

I have 3 SQL tables.
clients
events
client_events
Because a client can have multiple events, I made the third table to show those relationships. I am using the following code to retrieve all of the clients that have the have a record matching this event, but it is only returning 1 record when there are multiple.
$eventHosts = DB::table('clients')->whereIn('id', function($query) {
$query->select('client_id')->from('client_events')->where('event_id', '=', explode('/', $_SERVER['REQUEST_URI'])[2]);
})->get();
What am I overlooking?
You can fetch the ids first, then pass to the whereIn query.
$clientIds = DB::table('client_events')
->where('event_id', explode('/', $_SERVER['REQUEST_URI'])[2])
->pluck('client_id')
->toArray();
$eventHosts = DB::table('clients')->whereIn('id', $clientIds)->get();
To get the results in a single query and more efficeintly, try join
$eventHosts = DB::table('clients') //select your main table
->join('client_events','client_events.client_id','=','clients.id') //join it on related columns
->where('client_events.client_id',explode('/', $_SERVER['REQUEST_URI'])[2])) //apply your condition on client_events
->get();

Display Json data in laravel view with Joins

I'm trying to retrieve data from database to laravel blade view with join associate table.
in my case I have two tables called interesting_courses and courses. here some student can have many interesting courses. Therefore courses_id stored as json array in database as follows.
["1","11","15","16"]
but I need to join the courses table to get the associate course name as follows.
["Hospitality","Business Management","Auto Mobile","Health Care"]
Below is my controller
$intresting_courses = DB::table('intresting_courses')
->join('courses','courses.id','=','intresting_courses.courses_id')
->where('intresting_courses.youth_id',$id)
->first();
How can I join the tables.
There is no way you can join it in query natively.
The solution is to write two queries
select * from intresting_courses where youth_id = ? limit 1
select * from courses where id in (1, 2, 3, 4, 5, ...)
that way you can get courses that student intresting.
Here the laravel code for thoses queries.
$intresting_courses = DB::table('intresting_courses')
->where('intresting_courses.youth_id', $id)
->first();
$courses = DB::table('courses')
->whereIn('id', json_decode($intresting_courses->courses_id))
->get();

How to select all the values from a table except the values which are in foreign table?

I have three tables:tbl_borrower, tbl_clientandtbl_guarantor
tbl_Client:
id|name|address|email|
tbl_Guarantor:
id|clientid(fk)|Guaranteed_date|borrower_id(fk from borrower table)
I want to retrieve all the values of client table except the values which are present in guarantor table in the controller of Laravel 5.5.
Once you have the models and relationships set up, you should just do:
Client::doesntHave('guarantor')->get()
https://laravel.com/docs/5.6/eloquent-relationships#querying-relationship-absence
If you're using the query builder, it would be:
$clients = DB::table('tbl_clients')
->join('tbl_guarantor', 'tbl_clients.id', '=', 'tbl_guarantor.clientid')
->select('tbl_clients.*')
->whereNull('tbl_guarantor.clientid')
->get();
https://laravel.com/docs/5.5/queries
With the premise of using a left join and testing for NULL on the 2nd table id based on this answer. https://stackoverflow.com/a/4076157/3585500
Try this :
DB::table('tbl_Client')
->groupBy('tbl_Client.id')
->leftjoin('tbl_Guarantor', 'tbl_Client.id', '=', 'tbl_Guarantor.clientid')
->get([
'tbl_Client.*'
]);

Categories