Laravel query builder SUM returns multiplied values - php

I have the following query and been fighting with from yesterday after solving previous issue with the help of great stack-overflowers yesterday's question.
$sales = DB::table('sales')
->leftJoin('store_configs', 'store_configs.id', '=', 'sales.store_config_id')
->leftJoin('category_sales', 'category_sales.sale_id', '=', 'sales.id')
->leftJoin('categories', 'categories.id', '=', 'category_sales.category_id')
->leftJoin('departments', 'departments.category_id', '=', 'categories.id')
->leftJoin('department_sales', 'department_sales.sale_id', '=', 'sales.id')
->select('sales.date',
DB::raw('sales.id as sales_id'),
DB::raw('(IFNULL(sum(department_sales.amount), 0)) as department_sales'),
DB::raw('(IFNULL(sum(category_sales.amount), 0)) as cat_total')
)
->groupBy('date', 'sales.id')->orderBy('date', 'desc')->get();
The following is the result output from above query and it is wrong:
I have a table structure with following data: categories_sales has following data:
department_sales
As per the table : I expected result should have been :
department_sales: 10 for sale_id = 1
department_sales: 5 for sale_id = 2
category_sales: 200 for sale_id 1
category_sales: 30 for sale_id 2
Can someone please give me some idea ? I will be really really thankful.

Related

I want to find duplicate data from the database and show sum of duplicate data in laravel 8

I want to get all the data from SALES and PURCHASES table but I want to show product name for the single time and also want to show the sum of its quanitity..
How can i do this in laravel 8 ?
What will be the query ??
$stock = DB::table('products')
->join('purchases','purchases.product_id','products.id')
->join('sales','sales.product_id','products.id')
->groupBy('product_id')
->get();
I dont have your whole query but use havingRaw to find the duplicates.
$dups = DB::table('tableName')
->select('col1_name','colX_name', DB::raw('COUNT(*) as `count`'))
->join('purchases','purchases.product_id','products.id')
->join('sales','sales.product_id','products.id')
->groupBy('col1_name', 'ColX_name')
->havingRaw('COUNT(*) > 1')
->get();
Maybe something like that
$stock = DB::table('products')
->select('sales.*','purchases.*','products.name', DB::raw('products.name as `NbProduct`'))
->join('purchases','purchases.product_id','products.id')
->join('sales','sales.product_id','products.id')
->groupBy('sales.id', purchases.id)
->get();

Laravel relation between 5 tables

please what is the correct way of getting data from the MN table where one product has assigned multiple combinations of Mark / Model / Year.
E.g. product with ID 1 has following in mmis table:
id | product_id | mark_id | model_id | year_id
178 1 1 1 2
177 1 2 1 3
176 1 3 1 1
other tables are: marks, models, years.
It's completely fine getting all requested data with just:
$items = ProductMmi::where('product_id', $id)
->with(['mark', 'model', 'year'])
->get();
The problem is, that in this way I am not able to sort result based on mark.name ASC, model.name ASC, year.name ASC.
Thank you for any advice.
update:
forgot to add my second try - ordering still in troubles...
$items = ProductMmi::select([
'product_mmis.*',
'marks.*',
'mark_models.*',
'mark_model_years.*'
])
->join('marks', 'product_mmis.mark_id', '=', 'marks.id')
->join('mark_models', 'product_mmis.model_id', '=', 'mark_models.id')
->join('mark_model_years', 'product_mmis.year_id', '=', 'mark_model_years.id')
->where('product_mmis.product_id', $id)
->orderBy('mark', 'asc')
->orderBy('model', 'asc')
->orderBy('year', 'asc')
->get();
you can use this way
$items = ProductMmi::where('product_id', $id)->with(['mark'=>function($query){
$query->orderBy('your_column_name','ASC');
}])->with(['model', 'year'])
->get();
or one thing if you dont want to edit your query then in the model you can do also like this
public function mark()
{
return $this->hasMany(Mark::class)->orderBy('mark','asc');
}
I think the solution was to add orderBy methods between specific joins. E.g. the following case is working completely properly:
$items = ProductMmi::select([
'product_mmis.*',
'marks.*',
'mark_models.*',
'mark_model_years.*'
])
->join('marks', 'product_mmis.mark_id', '=', 'marks.id')
->orderBy('mark', 'asc')
->join('mark_models', 'product_mmis.model_id', '=', 'mark_models.id')
->orderBy('model', 'asc')
->join('mark_model_years', 'product_mmis.year_id', '=', 'mark_model_years.id')
->where('product_mmis.product_id', $id)
->orderBy('year', 'desc')
->get();
Is there a better way to have it done in a more efficient way? Thanks.

Use query 2 in query 1 to get all data inside one query

I have 3 tables :
*hinteractions (id, name...)
*effects (id, name...)
*hinteractions_has_effects (hinteractons_id, effects_id)
I might have one to many effects in a hinteractions et one hinteraction might have one to many effects, that's why I have this join table.
I have this Eloquent query :
Query 1 :
$informations_plante = DB::table('herbs')
->select('herbs.name as hname', 'herbs.sciname', 'herbs.id as herbid','hinteractions.id as hinteractionid','hinteractions.note as hinteractionnote','hinteractions.force_id','targets.name as targetname', 'forces.name as force_name')
->leftJoin('hinteractions', 'herbs.id', '=', 'herb_id')
->leftJoin('forces', 'forces.id', '=', 'force_id')
->leftJoin('targets', 'targets.id', '=', 'hinteractions.target_id')->where('herbs.id', $id)
//I would like to use the query 2 here to select effects.name with hinteraction.id used in this query to get effects' name in this query (I might have one to many).
->get();
Query 2 :
$hinteractions_has_effects = DB::table('hinteraction_has_effects')
->select(DB::raw('effect_id, hinteraction_id','effects.name'))
->where('hinteraction_has_effects', '=', hinteraction.id (from the query 1))
->get();
With query 1, I retrieve some informations like hinteractions_id.
I would like to use those hinteractions_id and use them in the query 2.
The best way will be to merge both queries (1 and 2) to get only one Eloquent query.
Do you have any idea ?
Try below query and let me know if this is what you're looking for -
$informations_plante = DB::table('herbs')
->select('herbs.name as hname', 'herbs.sciname', 'herbs.id as herbid','hinteractions.id as hinteractionid','hinteractions.note as hinteractionnote','hinteractions.force_id','targets.name as targetname', 'forces.name as force_name', 'effects.id as effects_id', 'effects.name as effects_name')
->leftJoin('hinteractions', 'herbs.id', '=', 'herb_id')
->leftJoin('forces', 'forces.id', '=', 'force_id')
->leftJoin('targets', 'targets.id', '=', 'hinteractions.target_id')->where('herbs.id', $id)
//added below lines
->leftJoin('hinteraction_has_effects', 'hinteraction_has_effects.hinteractons_id', '=', 'hinteractions.id')
->leftJoin('effects', 'hinteraction_has_effects.effects_id', '=', 'effects.id')
->get();
HTH!

How to count where using DB::raw() in laravel?

I have this query, but it does not work
$order = Order::select('*', DB::raw('count(*) as num_product'),
DB::raw('count(status) where status = 1 as accepted')) // ERROR HERE
->groupBy(DB::raw("DATE_FORMAT(created_at, '%Y-%m-%d')"))->get();
I want to show number of order that accepted, for example : 2 of 5
$order = Order::select(DB::raw('count(*) as num_product, status'))
->where('status', 1)
->groupBy('status')
->groupBy(DB::raw("DATE_FORMAT(created_at, '%Y-%m-%d')"))
->get();

Pagination eloquent

I want to paginate ordering by linkscount em ASC...
The table pages:
----------------------
id | name
----------------------
1 | Globo
----------------------
2 | Google
----------------------
3 | MC Donalds
----------------------
4 | Habibs
The query to FIRST PAGE RESULTS (order/query is OK):
$pages = Mypages::where('pages.author_id', auth()->user()->id)
->orderBy('linkscount', 'desc')
->leftJoin('links', 'links.page_id', '=', 'pages.id')
->selectRaw('pages.*, count(links.id) as linkscount')
->groupBy('pages.id')
->take(2)
->get();
The query TO PAGINATE (order/query is not ok):
$pages = Mypages::where('pages.author_id', auth()->user()->id)
->orderBy('linkscount', 'asc')
->leftJoin('links', 'links.page_id', '=', 'pages.id')
->selectRaw('pages.*, count(links.id) as linkscount')
->groupBy('pages.id')
->where('pages.id', '>', $id)
->take(2)
->get();
This query, don't return nothing, it was to return "MC Donalds"...
$id = LAST ID DISPLAYED.
Like Jacob H said in the comment, this isn't a real SQL, because the group by function need to have all the columns of the query that you have in the select except the functions like counts, sums, etc.
For this example you need to put the pages.name and pages.id in the group by
$pages = Mypages::where('pages.author_id', auth()->user()->id)
->orderBy('linkscount', 'asc')
->leftJoin('links', 'links.page_id', '=', 'pages.id')
->selectRaw('pages.id, pages.name, count(links.id) as linkscount')
->groupBy('pages.id', 'pages.name')
->where('pages.id', '>', $id)
->take(2)
->get();
And if you are sending the correct $id, everything seems ok.

Categories