Based on my question earlier Get Data from Array
it turns out that in only shows one record with completed SUM value.
I've been trying to add GROUP_BY clause like this:
$this->db->select('t1.act_id, t2.login, t1.cust_name, t1.act_type, t1.act_detail, t1.date_added, t1.date_modified, t1.act_notes, '
. 't3.category, t1.total_time, SUM(t1.total_time) as total')
->from('activity as t1')
->join('user as t2', 't1.user_id = t2.user_id', 'LEFT')
->join('customer as t3', 't1.cust_name = t3.cust_name', 'LEFT')
->where('t2.login', $user)
->where('MONTH(t1.date_added)', $month)
->group_by ('t1.user_id');
Unless I remove the SUM statement, the result still the same one record with complete SUM.
meanwhile if I change the GROUP_BY parameter into (t1.act_id) which is the primary key of that table, all records showing but the sum isn't (it only show SUM value of the first record only).
Any help would be appreciated. thank you.
Related
So I have the following query, which is working:
Expense::select('amount', 'date', DB::raw('COUNT(*) as `count`'))
->groupBy('amount', 'date')
->havingRaw('COUNT(*) > 1')
->get();
This is to grab all expenses that are potential duplicates (same amount and same date). However, I want to grab everything, not only the amount and date. The following is not working:
return Expense::select('name', 'amount', 'date', DB::raw('COUNT(*) as `count`'))
->groupBy('amount', 'date')
->havingRaw('COUNT(*) > 1')
->get();
This will give me this error:
SQLSTATE[42000]: Syntax error or access violation: 1055 Expression #1 of the SELECT list is not in the GROUP BY clause and contains a nonaggregated column
I have many more fields for an Expense that I want to list in my view, most importantly of course the name, but also the slug so I can link to each potential duplicate, etc.
Also, the second "issue", but not the most important one, is that with the above query, all expenses are returned in one collection. They are not grouped by date for example.
The most desirable would be to have the results somewhat like this. All potential duplicates should be grouped by the date so I can do something like this in my view:
#foreach($duplicates as $date => $expenses)
#foreach($expenses as $expense)
{{ $date }}
// List all expenses for that date.. etc.
Question 1: How would I make the above query work with all database fields, not only the date and amount?
Question 2: How would I be able to grab the potential duplicates and group them by date so I can loop over the dates and the expenses like in the above example?
Always handle column properly when doing grouping
e.i. you can specify all the fields you want to select in groupBy
// database query
$expenses = Expense::select(['amount', 'date', 'name', 'slug'])
->selectRaw('count(*) AS count')
->havingRaw('count > 1')
->groupBy(['amount', 'date', 'name', 'slug'])
->get();
// Another date grouping done in collection
return $expenses->groupBy('date');
or something like combing columns that belongs to your desired grouping
return Expense::select('date')
->selectRaw('group_concat(name) as names') // comma separated names belongs to the group
->selectRaw('group_concat(amount) as amounts') // comma separated amounts belongs to the group
->selectRaw('group_concat(slug) as slugs')// comma separated slugs belongs to the group
->selectRaw('count(*) AS count')
->havingRaw('count > 1')
->groupBy('date')
->get();
EDIT
If you only want to group them by date and still have the actual rows of duplicate, you can just add another select statement to count for date duplicate without grouping them by date in your query, and do the date grouping in collection.
e.i.
$expenses = Expense::select( ['amount', 'date', 'name', 'slug'] )
->selectRaw('(SELECT COUNT(date) FROM expenses t1 WHERE t1.date = expenses.date ) as duplicates')
->havingRaw('duplicates > 1')
->get();
return $expenses->groupBy('date');
Then the output should have another column duplicates which has the number of duplicate each date has and still has all the rows for duplicate dates
I have a table (A) that has a One to Many relation with another table (B).
I want to query Table A and eager load Table B with the Table A results - but I also want to sort Table A by a value in Table B.
I have tried using OrderBy in the query and also trying SortBy on the resultant collection but cannot get the Table A data to be sorted by the value found in Table B.
Example of what I have tried:
$query = ModelA::with("ModelB"])->get()->sortByDesc('ModelB.sortValue');
Keep in mind, I am only interested in the LATEST record from Table B. So I need to query Table A and sort by a value in the LATEST records of Table B.
How can I achieve this?
EDIT:
The below (as suggested by #ljubadr) works pretty close, but the issue is that there are many record in Table B which means that it doesn't reliably sort as it doesn't seem to sortby the latest records in Table B. Can I have the join return ONLY the latest record for each ID?
$query = ModelA::select('TableA.*')
->join('TableB', 'TableA.id', '=', 'TableB.col_id')
->groupBy('TableA.id')->orderBy('TableB.sortCol', 'desc')
->with(['x'])
->get();
EDIT 2:
#Neku80 answer has gotten me closest but it seems to not sort the column with the greatest accuracy.. I'm sorting a Decimal column and for the most part it is in order but in some places the items are out of order..
$latestTableB = ModelB::select(['TableA_id', 'sortByColumnName'], DB::raw('MAX(created_at) as created_at'))
->groupBy('TableA_id');
$query = ModelA::select('TableA.*')
->joinSub($latestTableB, 'latest_TableB', function ($join) {
$join->on('TableA.id', '=', 'latest_TableB.TableA_id');
})
->orderBy('latest_TableB.sortByColumnName')
->get();
For example, the ordering is like:
0.0437
0.0389
0.0247 <-- -1
0.025 <-- +1
0.0127
When I delete all rows except for the 'latest' rows, then it orders correctly, so it still must be ordering with old data...
I have found a solution:
ModelA::select('TableA.*', 'TableB.sortByCol as sortByCol')
->leftJoin('TableB', function ($query) {
$query->on('TableB.TableA_id', '=', 'TableA.id')
->whereRaw('TableB.id IN (select MAX(a2.id) from TableB as a2 join TableA as u2 on u2.id = a2.TableA_id group by u2.id)');
})
->orderBy('TableB.sortByCol')
->get();
Another alternative to order is like this:
$users = User::orderBy(
Company::select('name')
->whereColumn('companies.user_id', 'users.id'),
'asc'
)->get();
Here we are ordering in asc order by company name field.
In this article it is explained in detail.
You can simply execute a left join query:
ModelA::query()->leftJoin('model_b_table', 'model_a_table.primary_key', '=', 'model_b_table.foreign_key')->orderBy('model_a_table.target_column')->get();
This should work if you only need TableB's ID and created_at columns:
$latestTableB = ModelB::select('TableA_id', DB::raw('MAX(created_at) as created_at'))
->groupBy('TableA_id');
$query = ModelA::select('TableA.*')
->joinSub($latestTableB, 'latest_TableB', function ($join) {
$join->on('TableA.id', '=', 'latest_TableB.TableA_id');
})
->orderBy('latest_TableB.created_at')
->get();
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()
I have a query that will get the data from a joined tables. I successfully fetched the data from the 2 tables but for a long time, I did not notice that only one primary id of a certain table has been returned. I made adjustments but still never figure it out. What would I do? Please help. Thanks a lot guys. Here is my code.
$purchase = Purchase::where('purchases.purchase_order_id', $id)
->join('products', 'purchases.product_id', '=', 'products.id')
->select('purchases.*', 'products.*')
->get();
It only returns the primary id of a product, primary id of the table purchases is not included. What is the problem of the query above?
You can use select as:
->select('purchases.*', 'purchases.id as purchase_id', 'products.*', 'products.id as product_id')
This query returns the IDs of Survey Table as surveys_id as well as IDs of industries table along with all other data:
surveydata = Survey::select(
'surveys.*',
'surveys.id as surveys_id',
'industries.*',
'industries.id as industries_id'
)->where('surveys.active_status', '=','1')
-> join (
'industries',
'industries.id',
'=',
'surveys.survey_industry_id'
)->orderBy('surveys.id','desc')
->paginate(12);
I have an database with tablenames like this: tbl_accessoires_1, tbl_accessoires_2 etc. In my main table is a column that gives me the number for the table I have to join. But how do I get this value if I use ->all().
This is my query:
$query = (new Query())
->select([
'a.id id',
'a.soort soort',
])
->from('auto_new a')
->leftJoin('tbl_accessoires_--soort-- acc', 'acc.id = a.id')
->all();
So the a.soort in the select must be at the --soort--
Is there any way to do this?
If I only get one car it is possible because I could get the soort value before this query. but how do I do this when I want to get all cars
So because it's not possible in my situation I've just made a new query to get the options. This will do for now because I don't really need the options when I get all cars.