I have a query in which I need to add a column (is_found) on the base of another table "history", if product_id exists on a table "history" then the column value (is_found) became 1 otherwise its value remains 0.
Here is my query:
Product::select(
'products.id as product_id',
'products.name',
'products.desc',
'products.image',
'products.barcode',
'categories.name as category_name',
'categories.id as category_id',
)
->leftJoin(
'categories',
'products.category_id',
'=',
'categories.id'
)
Try this:
Product::select(
'products.id as product_id',
'products.name',
'products.desc',
'products.image',
'products.barcode',
'categories.name as category_name',
'categories.id as category_id',
\DB::raw('IF(history.product_id, 1, 0) AS is_found')
)
->leftJoin(
'categories',
'products.category_id',
'=',
'categories.id'
)
->leftJoin('history', 'products.id','=','history.product_id')
Or:
Product::select(
'products.id as product_id',
'products.name',
'products.desc',
'products.image',
'products.barcode',
'categories.name as category_name',
'categories.id as category_id',
\DB::raw('IF((select product_id from history where history.product_id = products.id), 1, 0)')
)
->leftJoin(
'categories',
'products.category_id',
'=',
'categories.id'
);
You can use sub-select with exists
Product::select(
'products.id as product_id',
'products.name',
'products.desc',
'products.image',
'products.barcode',
'categories.name as category_name',
'categories.id as category_id',
)
->selectRaw('exists (select * from history where history.product_id = products.id) as is_found')
->leftJoin('categories', 'products.category_id', '=','categories.id')
Related
Hi I would like to ask is there any way to refer the 2 foreign key to 1 primary table id?
This is my code.
$job_postings = JobPosting::select(
'job_postings.id as job_posting_id',
'job_postings.qualifications',
'job_postings.created_at',
'job_postings.updated_at',
'job_postings.created_by',
'job_postings.approved_by',
'dealerships.dealership_name',
'departments.department_name',
'positions.position_name',
'users.name as created_by_name', (**This is the issue please help**)
'users.name as approved_by_name', (**This is the issue please help**)
DB::raw("case when job_postings.status = 0 then 'Pending' else 'Approved' end status"),
)
->leftJoin('dealerships', 'job_postings.dealership_id', '=', 'dealerships.id')
->leftJoin('departments', 'job_postings.department_id', '=', 'departments.id')
->leftJoin('positions', 'job_postings.position_id', '=', 'positions.id')
->leftJoin('users', 'job_postings.created_by', '=', 'users.id', 'job_postings.approved_by', '=', 'users.id')
->where('job_postings.id', $jp_id)
->get();
$data = [];
foreach($job_postings as $j => $job_posting){
$data[] = [
'job_posting_id' => $job_posting->job_posting_id,
'dealership_name' => $job_posting->dealership_name,
'department_name' => $job_posting->department_name,
'position_name' => $job_posting->position_name,
'qualifications' => $job_posting->qualifications,
'status' => $job_posting->status,
'created_by' => $job_posting->created_by_name,
'approved_by' => $job_posting->approved_by_name,
'created_at' => $job_posting->created_at->format('D, d M Y').date(' | h:i A', strtotime($job_posting->created_at)),
'updated_at' => $job_posting->updated_at->format('D, d M Y').date(' | h:i A', strtotime($job_posting->updated_at)),
];
}
Under the last leftJoin
->leftJoin('users', 'job_postings.created_by', '=', 'users.id', 'job_postings.approved_by', '=', 'users.id')
the approved_by is a foreign key pointing to users id and created_by is also a foreign key pointing to users id.
What I am aiming at is to get the name of the user but in separate reference.
Somewhat similar to this analogy .
'users.name = created_by as created_by_name',
'users.name = approved_by as approved_by_name',
approved_by = user.id => user.name
created_by = users.id => user.name
Thanks.
leftJoin('users','job_postings.created_by','=','users.id', 'job_postings.approved_by', '=', 'users.id')
Try this,
->leftJoin('users', function($join){ $join->on('users.id', '=', 'job_postings.created_by'); $join->on('users.id', '=', 'job_postings.approved_by'); })
I need to combine two queries into one so i can call it one time on my foreach inside a table in my blade view. I tried using merge() but it displays two separate queries. CountofPatents are all the patents that were submitted by a user and CountofApprovedPatents are the patents which has the status of "2". Here's how it looks now:
array 0 [person_id : 1
CountofApprovedPatents: 4
status: 2]
array 1 [person_id : 2
CountofApprovedPatents: 2
status: 2]
array 2 [person_id : 1
CountofPatents: 5]
array 3 [person_id : 2
CountofPatents: 4]
Here's how it's supposed to look like
array 0 [person_id : 1
CountofApprovedPatents: 4
CountofPatents: 5]
array 1 [person_id : 2
CountofApprovedPatents: 2
CountofPatents: 4]
Here's my code so far
AdminController
$start = $request->input('start');
$end = $request->input('end');
$approvedPatents = DB::table('patents')
->select('person_id', DB::raw('count(*) as CountofApprovedPatents'))
->where([
['status', '=', 2],
['date_approved', '>=', $start],
['date_approved', '<=', $end],
])
->groupBy('person_id')
->orderBy('status', 'desc')
->get();
$totalPatents = DB::table('patents')
->select('person_id', DB::raw('count(*) as CountofPatents'))
->where([
['date_approved', '>=', $start],
['date_approved', '<=', $end],
])
->groupBy('person_id')
->orderBy('status', 'desc')
->get();
$patents = $approvedPatents->merge($totalPatents);
$results = $patents->all();
return view('admin.patents.showPatents', compact('results',
'start', 'end'));
Is it possible to combine these two queries?
$results = DB::table('patents')
->union($approvedPatents)
->union($totalPatents)
->get();
What I think you are looking for is Unions.
It'll allow you to specify a query and then join it with the final query.
Eg.
$first = DB::table('users')
->whereNull('first_name');
$users = DB::table('users')
->whereNull('last_name')
->union($first)
->get();
Try:
$approvedPatents = DB::table('patents')
->select('person_id', DB::raw('count(*) as CountofApprovedPatents, status'))
->where([
['status', '=', 2],
['date_approved', '>=', $start],
['date_approved', '<=', $end],
])
->groupBy('person_id')
->orderBy('status', 'desc')
$totalPatents = DB::table('patents')
->select('person_id', DB::raw('count(*) as CountofPatents'))
->where([
['date_approved', '>=', $start],
['date_approved', '<=', $end],
])
->groupBy('person_id')
->orderBy('status', 'desc')
->union($approvedPatents)
->get();
Otherwise you could be looking for Joins - worth a look at the docs :)
Unions: https://laravel.com/docs/5.8/queries#unions
Joins: https://laravel.com/docs/5.8/queries#joins
You can use MySQL's IF condition in your raw selection of columns.
$results = DB::table('patents')
->select('person_id',
DB::raw('sum(IF(status = 2,1,0)) as CountofApprovedPatents'),
DB::raw('count(*) as CountofPatents')
->where([
['date_approved', '>=', $start],
['date_approved', '<=', $end],
])
->groupBy('person_id')
->orderBy('status', 'desc')
->get();
The above IF condition in sum() adds 1 to the result if current row's status is 2, else it adds 0 which effectively doesn't break the sum.
How can I pass the value of lead_id to my attendance table?
Here is the code from my controller
$scores = Score::with('lead','subject')->get()->groupBy('lead_id');
I want to pass $scores here:
$atnds = DB::table('attendances')
->select(DB::raw('count(*) as total, status'))
->where('status', '=', 'P')
->whereBetween('days', [$from,$to])
->groupBy('status')
**->where('lead_id','=',$scores)**
->get();
Both table Score and Attendance has lead_id is it possible to connect them? i want to perform total base on the lead_id from score table is equal to attendance table. with my code i'm getting this empty array
try this:
$scores = Score::with('lead','subject')->get();
$atnds = DB::table('attendances')
->select(DB::raw('count(*) as total, status'))
->where('status', '=', 'P')
->whereBetween('days', [$from,$to])
->groupBy('status')
->whereIn('lead_id', array_column($scores->toArray(), 'lead_id'))
->get();
where condition in eloquent expects a string/integer value to be pased and not a collection as you are trying to pass it.
After you get the results from this query:
they should be grouped by keys like:
$scores = Score::with('lead','subject')->get()->groupBy('lead_id');
Collection{
1 => Collection{somedata},
2 => Collection{somedata},
}
So i pressume you need only the keys from this collection:
$atnds = DB::table('attendances')
->select(DB::raw('count(*) as total, status'))
->where('status', '=', 'P')
->whereBetween('days', [$from,$to])
->groupBy('status')
->whereIn('lead_id',$scores->pluck('lead_id')->toArray())
->get();
this is the result of DD$scores
"id" => 62
"subject_id" => 4
"lead_id" => 5
"uuid" => "36c850d0-9ec9-11e8-85e1-cdb65cbc1965"
"created_at" => "2018-08-13 07:19:27"
"updated_at" => "2018-08-13 07:19:27"
]
the total is not there
I have a question i have 4 tables
Deals
Lists
Lists_Galleries
List_has_deals
Lists_has_gallery
I need to obtain the img_src_list what is in the List_Galleries but from deals.
I have this var in this time
$query = ListsDeals::where( $matchDeals )
->where('stock', '>', 0)
->orwhere( $matchOtherDeals )
->whereDate('end_date', '>', date('Y-m-d'))
->limit( 4 )
->offset( 0 )
->orderBy( 'start_date' );
$deals = $query->join( 'list_has_deals', 'deals.id', '=', 'list_has_deals.deal_id' )
->join( 'lists', 'list_has_deals.list_id', '=', 'lists.id' )
->join( 'list_has_gallery', 'lists.id', '=', 'list_has_gallery.list_id' )
->join( 'lists_galleries', 'list_has_gallery.gallery_id', '=', 'lists_galleries.id' )->get();
This Give me the results but how i have the same name in all tables for example title for deals and lists that overwrite the names and dont get the values correct, how i can obtain certain columns without overwrite the others? regards.
UPDATE
This give me always the same deal for all results.
$deals = $query->join( 'list_has_deals', 'deals.id', '=', 'list_has_deals.deal_id' )
->join( 'lists', 'list_has_deals.list_id', '=', 'lists.id' )
->join( 'list_has_gallery', 'lists.id', '=', 'list_has_gallery.list_id' )
->join( 'lists_galleries', 'list_has_gallery.gallery_id', '=', 'lists_galleries.id' )
->select([ 'deals.id as deal_id', 'deals.stock as stock', 'deals.price as price', 'deals.price_reduced as price_reduced', 'deals.img_src as img_src', 'deals.title_deal as deal_title' ])->get();
UPDATE
$deals = $query->join( 'list_has_deals', 'deals.id', '=', 'list_has_deals.deal_id' )
->join( 'lists', 'list_has_deals.list_id', '=', 'lists.id' );
$other = $deals->join( 'list_has_gallery', 'lists.id', '=', 'list_has_gallery.list_id' )
->join( 'lists_galleries', 'list_has_gallery.gallery_id', '=', 'lists_galleries.id' )
->select([ 'deals.id', 'deals.stock', 'deals.price', 'deals.price_reduced', 'deals.img_src', 'deals.title_deal', 'lists_galleries.img_src_list' ])
->addSelect([ 'lists_galleries.img_src_list' ])
->get();
You can use select() to choose only those columns you want, and use aliases to rename any that clash:
$query->select(['lists.title AS title', 'lists_galleries.name AS name', 'lists.id AS id'])->get();
That way you can cherry-pick only those columns you need and deal with clashes easily.
Is there a way to Select all where a join fails:
something like:
// Pseudo
$unit = User::from( 'users' )
->select( 'users.*' )
->whereJoinFails( 'suppliers', 'users.id', '=', 'suppliers.user_id' );
I have tried:
// Returns all users
$unit = User::from( 'users' )
->select( 'users.*' )
->leftJoin( 'suppliers', 'users.id', '=', 'suppliers.user_id' );
and
// Returns all users but the one that doesn't satisfy is duplicated
$unit = User::from( 'users' )
->select( 'users.*' )
->join( 'suppliers', 'users.id', '!=', 'suppliers.user_id' );
Left Join will always display the data on the left side of the join even if it is null. This way you can see all the records that are missing in the suppliers table because it will show up as a null. This should work:
User::from( 'users' )
->select( 'users.*' )
->leftJoin('suppliers', 'users.id', '=', 'suppliers.user_id')
->whereNull('suppliers.user_id')
->get();
Alternative solution for this would be:
$cat = User::whereNotIn('id',
DB::table('suppliers')->distinct()->lists('user_id')
)->get();
but in this case 2 queries to database would be executed, for example:
select distinct `user_id` from `suppliers`;
select * from `users` where `id` not in ('1', '2', '5', '6', '7', '8', '9', '10');