Laravel join with limit - laravel

I have the following working for laravel paginate
$query = DB::table('clients')
->leftJoin('radusergroup', 'clients.username', '=', 'radusergroup.username')
->leftJoin('recharge', 'clients.username', '=', 'recharge.soldto');
I want to join some values from two tables radusergroup and recharge. radusergroup always return one row as it has only one row stored whereas recharge table return multiple rows. I want only one row returned from recharge table which is latest entry.
Right now its return all the possible rows from recharge table and showing it on paginated view.

This is Laravel Official documentation
DB::table('clinets')
->leftJoin('radusergroup', 'clients.username', '=', 'radusergroup.username')
->leftJoin('recharge', function ($leftJoin) {
$leftJoin->on('clients.username', '=', 'recharge.soldto')
->where('recharge.create_date', '=', DB::raw("(select max(`create_date`) from recharge)"));
})
->get();
this is the case if you have create_date column in your table, if you haven't got it I strongly recommend to create that column.

Related

how to retrieve multiple table data with multiple criteria in laravel eloquent?

I want to retrieve data from 4 different table using laravel eloquent with multiple criteria.
an Overview of my table;
table 1
id
name
table 2
id
name
year
table1_id
table 3
id
name
description
table2_id
table 4
id
name
quarter
table3_id
below are their relations
table 1
hasMany -> table 2
table 2
belongsTo ->table1
HasMany->table2
table 3
belongsTo ->table2
HasMany->table3
table 4
belongsTo ->table3
I'd like to fetch the data by resource show with two parameters
and i tried this
$Report = Table1::whereHas('tabke1', function($query){
$query->where('year', 'like','%'.$year.'%');
})
->with('table2')->whereHas('table3', function($query){
$query->where('quarter', 'like', '%'.$quarters.'%');
})
->get();
but im receiving syntax error.
How can I retrieve the data from multiple table with multiple filter?
i tried this table query to understand more what i expect
SELECT `table1`.*, `table2`.*, `table3`.*, `table4`.*
FROM `table1`, `table2`, `table3`, `table4`
WHERE ((`table2`.* year = 2019) AND (`table4`.* quarter = 1))
I reckon there are two queries to achieve the results.
The first query is something like:
Table1::whereHas('table2', function ($query) {
$query->where('year', 2019);
})
->whereHas('table2.table3.table4', function ($query) {
$query->where('quarter', 1);
})
->get();
The second query is something like:
Table1::select('table1.*')
->join('table2', 'table1.id', '=', 'table2.table1_id')
->join('table3', 'table2.id', '=', 'table3.table2_id')
->join('table4', 'table3.id', '=', 'table4.table3_id')
->where('table2.year', 2019)
->where('table4.quarter', 1)
->distinct()
->get();
Regarding performance, I prefer the second query.

How to make laravel 5.2 pagination work(count) on just main table records not include the join tables

$employees = DB::table('users')
->leftJoin('assigned_branches','assigned_branches.user_id','=','users.id')
->leftJoin('assigned_geo_infos','assigned_geo_infos.id' ,'=','assigned_branches.region_branch_id')
->leftJoin('user_customers','user_customers.user_id','=','assigned_branches.user_id')
->leftJoin('customers','customers.id','=','user_customers.customer_id')
->whereIn('assigned_geo_infos.project_id',$assigned_projects_ids)
->where([['users.office_staff',0],['users.active',$filter]])
->select('assigned_geo_infos.*','assigned_geo_infos.id as info_id','assigned_geo_infos.name as info_name','assigned_branches.*','assigned_branches.level as region_branch_level','users.*','customers.customer_name')
->paginate(15);
So here i want to pagination process or calculation on just users table not on other table means join table.According to users total count should be 2 but due to join its is giving total page 8. Or is there any other solution in which i can get all join table records as sub array of main table record array.
Use groupBy() method, to group the results:
$employees = DB::table('users')
->leftJoin('assigned_branches','assigned_branches.user_id','=','users.id')
->leftJoin('assigned_geo_infos','assigned_geo_infos.id' ,'=','assigned_branches.region_branch_id')
->leftJoin('user_customers','user_customers.user_id','=','assigned_branches.user_id')
->leftJoin('customers','customers.id','=','user_customers.customer_id')
->whereIn('assigned_geo_infos.project_id',$assigned_projects_ids)
->where([['users.office_staff',0],['users.active',$filter]])
->select('assigned_geo_infos.*','assigned_geo_infos.id as info_id','assigned_geo_infos.name as info_name','assigned_branches.*','assigned_branches.level as region_branch_level','users.*','customers.customer_name')
->groupBy('users.id')
->paginate(15);

Laravel join two tables with where that compares two date time columns

I have two tables that I want to run joint query on using the value of two date time columns, I have products table and sync_status tables, I want to return all products with updated_at date time greater than synced_at date time.
DB::table('products')
->join('sync_statuses', function ($join) {
$join->on('products.product_number', '=', 'sync_statuses.product_number')
->where('products.updated_at', '>', 'sync_statuses.synced_at')
->whereNull('products.deleted_at');
})
->select('products.product_number');
This SQL represents what I am trying to achieve using Eloquent:
SELECT products.product_number
FROM products
JOIN push_statuses
ON products.product_number = statuses.product_number
AND (
statuses.synced_at IS NULL
OR products.updated_at > statuses.synced_at
)
You have to use on() instead of where() to compare columns:
->on('products.updated_at', '>', 'sync_statuses.synced_at')
This worked for me:
DB::table('products')
->join('statuses', function ($join) {
$join->on('products.product_number', '=', 'statuses.product_number')
->where(DB::raw('products.updated_at'), '>=', DB::raw('statuses.synced_at'))
->whereNull('products.deleted_at');
})->select('products.product_number');
I needed to use DB::raw('products.updated_at') to reference each date time column in the where() clause.

Laravel Left Join Query

I am using laravel 5.3 and I have some left join query with error in laravel query method.
This is my normal query
SELECT bran.branchName,sch.schoolName From m_schoolbranch bran
LEFT JOIN m_students stu ON stu.schoolNo=bran.schoolNo AND stu.branchNo=bran.branchNo
LEFT JOIN m_school sch ON sch.schoolNo=stu.schoolNo where stu.userNo='0000000001';
And this is my new laravel Query
DB::table('m_schoolbranch')
->join('m_students', 'm_schoolbranch.schoolNo', '=', 'm_students.schoolNo')
->join('m_students', 'm_schoolbranch.branchNo', '=', 'm_students.branchNo')
->join('m_school', 'm_schoolbranch.schoolNo', '=', 'm_school.schoolNo')
->select('m_school.schoolName', 'm_schoolbranch.branchName')
->where('m_students.userNo',$userNo)
->get();
In these query I need to match two column in table m_students so I put like this
->join('m_students', 'm_schoolbranch.branchNo', '=', 'm_students.branchNo')
But i show error...
Tables in the query need to have unique names, otherwise the DB has no way of knowing which m_schoolbranch should be used when evaluating m_schoolbranch.schoolNo.
You could use unique table aliases in your join statements but I recommend using multiple conditions on the join. Just like you use in your original SQL query. See here: https://stackoverflow.com/a/20732468/4437888
DB::table('m_schoolbranch')
->join('m_students', function($join)
{
$join->on('m_schoolbranch.schoolNo', '=', 'm_students.schoolNo');
$join->on('m_schoolbranch.branchNo', '=', 'm_students.branchNo');
})
->join('m_school', 'm_schoolbranch.schoolNo', '=', 'm_school.schoolNo')
->select('m_school.schoolName', 'm_schoolbranch.branchName')
->where('m_students.userNo',$userNo)
->get();

laravel 4.2 and join function

$options = table::join('table1', function($join) {
$join->on('table1.table_id','=','table.id');
$join->take(1);
})->get();
Is there a way to do this, i get error on take function.
the table and table1 has one to many relation, and i'd like to have on join just the first record of table1.
Thanks
Vincenzo

Resources