How to combine two counts using Laravel - php

Using Laravel 8 for a restful API.
A table in the database has following fields
report_date , supervisor_id and supervisor_note
I want to retrieve a result that counts the number of reports on any given day date and also counts all of the null values in supervisor_notes field.
I am using the following Laravel code:
$reports=DB::table('reports')
->where('supervisor_id','like', '%'.$supervisor_id.'%')
->select('report_date', DB::raw('count(*) as total'))
->groupBy('report_date')
->get();
I don't know how to combine the code with the second count condition in the same query

You can use conditional aggregation here
$reports=DB::table('reports')
->where('supervisor_id','=', $supervisor_id)
->select([
'report_date',
DB::raw('count(*) as total'),
DB::raw('sum(case when supervisor_note is null or supervisor_note = "" then 1 else 0 end) as notes_total')
])
->groupBy('report_date')
->get();
Also if supervisor_id is integer column and $supervisor_id also holds integer value then use exact integer matching like = instead of using string comparison using like clause

Related

when running get() using queryBuidler, Object of class stdClass could not be converted to string

I am trying to run this SQL query:
SELECT head_account_id, account_id, created_on, result, COUNT(*) AS counter FROM notes
WHERE result = 'not_processed' AND created_on >= (now() - INTERVAL 3 DAY) AND created_on <= (now() - INTERVAL 8 HOUR)
AND account_id IN (SELECT id FROM accounts WHERE account_status = 'approved' AND demo = 0)
GROUP BY account_id
ORDER BY head_account_id, account_id, created_on DESC;
using Laravel querybuilder:
$appointments = DB::table('confirmed_appointments')
->select('head_account_id','account_id','created_on','result', DB::raw('count(*) as counter'))
->where('result', 'not_processed')
->where('created_on', '>=', DB::raw('now() - interval 3 day'))
->where('created_on', '<=', DB::raw('now() - interval 8 hour'))
->whereIn('account_id', $id)
->groupBy('account_id')
->orderBy('head_account_id')
->orderBy('account_id')
->orderBy('created_on', 'desc')
->get();
where $id is:
$id = DB::table('accounts')
->select('id')
->where('account_status','Approved')
->where('demo','0')
->get();
And this above query works properly - I've checked using dd().
I am running into an error at $appointments= ..... -> get():
"Object of class stdClass could not be converted to string"
I understand that get() usually returns a stdClass object, but I don't understand why I can't use get() at all. A lot of the other solutions say to use get() -> toArray(); however I can't even get get() to run properly.. If I don't run get() and run dd() on the results, I get an array of information about the query but not the results itself.
I am new to Laravel/PHP so I might be lacking in knowledge but I hope that somebody can help me.
thanks for your time!
You can try to retrieve an array of id values with pluck(), i.e.:
$id = DB::table('accounts')
->select('id')
->where('account_status','Approved')
->where('demo','0')
->pluck('id');
With get() you are retrieving, in the $id var, a collection of standard objects.
It's not about the get method that you run into that error. It's about what tou trying to do with result of that query. if you tring to echo the result of collection class it throws that error. you can not echo an object right?
According to documentation:
get() returns a collection object. it means it has array of results in it. in your case it return collection object that contains any record ids that mathes the query
first() return just one result contains one record
if you want only one id to return and can treated as string , so that you could echo it in your view you must use first() method instead.
coclusion:
If you want may ids use get(), and must foraech loop for every single result.
If you want may just one id use first();
But be aware even if you use first it returns std class, so in this case if you want to access id. you must write $result->id and echo it out.
In your case $id is a full row of your matched data and you need only the id column so you need to do this
$id = DB::table('accounts')
->select('id')
->where('account_status','Approved')
->where('demo','0')
->get();
//The ID column
$id = $id->id;

Get min(date), max(date) with group by eloquent laravel

This query is for getting other data with the highest value of date with the group by/unique. Here I used unique in place of group by.
My question is how to get min(date) and max(date) with group by/unique.
The group by/unique is for Dataset table's date field.
I have searched for this but not getting exact solution that how to get max and min date with group by/unique in laravel eloquent.
In table structure, there are multiple entries for one code so here I used group by/unique to get one record for the code.
There can be multiple dates as 02-01-2003,01-03-2007,01-01-2019, 01-07-2018... etc. with same/ different code. If I group by with code then get onmy one record per code. So here I want to select the max date [01-01-2019] and min date [02-01-2003].
Thanks in advance.
Controller:
$datasets = Dataset::where('user_id', $user_id)
->orderBy('date','desc')
->get(['code', 'access','user_id','date'])
->unique('code');
Finally I got solution but this can not be the exact solution but as I am beginner and not getting the exact solution I do this functionality as below:
I created two different queries to get min and max values.
$min_datasets = Dataset::where('user_id', $user_id)
->orderBy('date','asc')
->get(['code', 'access','user_id','date'])
->unique('code');
$max_$datasets = Dataset::where('user_id', $user_id)
->orderBy('date','desc')
->get(['code', 'access','user_id','date'])
->unique('code');
Try to select max and min date like this:
$datasets = Dataset::select('code', 'access','user_id', DB::raw('MAX(date) as max_date'), DB::raw('MIN(date) as min_date'))
->where('user_id', $user_id)
->orderBy('date','desc')
->get()
->unique('code');
$data = DB::table('table_name')->where('user_id',$user_id)
->select('code','access','user_id','date')
->whereBetween('date', [02-01-2003, 01-01-2019])
->groupBy('unique_column')
->get()

Laravel 5.4 Query Builder - Where condition with 2 table fields

So I'm trying to use a query on selecting products that are on Critical Level. So basically, if the product's quantity is lower than its reorder_point, it'll be considered as Critical.
Here's my query that I'm using:
$products = DB::table('inventory')
->where('quantity', '<=', 'reorder_point')
->orderBy('quantity', 'asc')
->get();
But it only shows once the quantity of that row is set to 0 or less. So I'm asumming that the value of re_orderpoint in the where condition is 0.
But everything works when I use this query in phpMyAdmin:
SELECT * from inventory where quantity <= reorder_point
Laravel gives you whereColumn for comparing columns of same table. You can do it like this:
$products = DB::table('inventory')
->whereColumn('quantity', '<=', 'reorder_point')
->orderBy('quantity', 'asc')
->get();
See docs here.
Hope you understand.

Is there an alternative syntax to Laravel's DB::raw() for querying against a column value?

I've got two integer fields sent and limit
I want to do the following.
$overdrawn = Store::select('id')
->where('status', '=', 'active')
->where('sent', '>=', 'limit')
->get();
Obviously this looks for columns where the integer value of sent is greater than or equal to the string 'limit' which is not the desired behaviour.
I know I can pass DB::raw('limit') but wondered if there's an alternative syntax that would achieve the same results?
since some people seem confused about the SQL I want to execute it is as follows.
SELECT `id` FROM `store` where `status` = 'active' and `sent` > `limit`;

Returning Array in mysql Select

I'm trying to group inventory results by the model and manufacturer name, display the amount of items matching and 1 result per grouping. With that said, I'd like to try and retrieve all inventory id's within the group. Wondering if this is possible... Any ideas?
FYI - I'm using Laravel, the line in question is the ->selectRaw(CambridgeID as CambridgeIDArray)
$getMatchingInventory = DB::table('inventory')
->selectRaw('*, count(*) as groupTotal')
->whereRaw("MATCH(ManufacturerNameMatch, SubCategoryNameMatch, MainCategoryNameMatch, Model_Name, Title_Override, Description_Old) AGAINST ('$final' IN BOOLEAN MODE)")
->selectRaw('CambridgeID as CambridgeIDArray')
->groupBy('Model_Name', 'ManufacturerNameMatch')
->having('Units_OnHand', '>=', '1')
->orderBy('ManufacturerNameMatch')
//->paginate(15);
->get();
try this
$getMatchingInventory = DB::table('inventory')
->select(DB::raw("GROUP_CONCAT(CambridgeID) as `CambridgeIDArray`, count(*) as `groupTotal`"))
->whereRaw("MATCH(ManufacturerNameMatch, SubCategoryNameMatch, MainCategoryNameMatch, Model_Name, Title_Override, Description_Old) AGAINST ('$final' IN BOOLEAN MODE)")
->groupBy('Model_Name', 'ManufacturerNameMatch')
->having('Units_OnHand', '>=', '1')
->orderBy('ManufacturerNameMatch')
->get();
You should be able to use GROUP_CONCAT for that, see: http://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html#function_group-concat
You can use specify output format options (e.g., SEPARATOR) and use additional string manipulation as needed within the GROUP_CONCAT.
(Fyi, using raw MySQL, at least for this question, would make it easier to parse.)

Categories