Laravel 5.4 Query Builder SUM() from two different tables - php

I'm having problems getting the SUM of a certain field from two tables.
So to start things off, here's my query.
//Getting of Cost of Goods Sold (Menus)
$totalMenuCost = DB::raw('(SUM(orders.qty * orders.cost)) as cost');
$yearMenuSold = DB::raw('YEAR(orders.created_at) as year');
$menuscost = DB::table('orders')
->where('status', 'served')
->select($totalMenuCost, $yearMenuSold);
//Getting of Cost of Goods Sold (Items)
$totalItemCost = DB::raw('(SUM(purchases.qty * purchases.cost)) as cost');
$yearItemSold = DB::raw('YEAR(purchases.created_at) as year');
$itemcost = DB::table('purchases')
->where('status', 'served')
->union($menuscost)
->select($totalItemCost, $yearItemSold)
->get();
And when I try to do return $itemcost. It returns two rows:
[
{
cost: "792.00",
year: 2017
},
{
cost: "1700.00",
year: 2017
}
]
I'm trying to make it return a single row but having it added, like this:
[
{
cost: "2492.00", // that's 1,700 + 792
year: 2017
}
]

$itemcost = DB::table('purchases')
->where('status', 'served')
->union($menuscost)
->select($totalItemCost, $yearItemSold)
->get();
In your Example you are just selecting $totalItemCost, $yearItemSold and union from other table ($menuscost).
So that won't add up the results.
///////////Try Changing your Query in this Format
select column1,sum(column2) total
from
(
select column1,column2
from Table1
union all
select column1,column2
from Table2
) t
group by column1
Hope this Helps..
Let me know if more help is needed.

All seems okay, Have you changed your $itemcost like this
$itemcost = DB::table('purchases')
->where('status', 'served')
->select($totalItemCost, $yearItemSold)
->union($menuscost)
->groupBy('year')
->get();
UPDATE
Since above not working for your case,
I think problem on group by is with union so Have a new try with this one.
$menuscost = DB::table('orders')
->where('status', 'served')
->select($totalMenuCost, $yearMenuSold)
->groupBy('year');
$itemcost = DB::table('purchases')
->where('status', 'served')
->select($totalItemCost, $yearItemSold)
->groupBy('year')
->union($menuscost)
->groupBy('year')
->get();
If this is not working then can you add output of this query.

Related

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();

Laravel: select students who do not have payment made in the month

I want to make a list of students who did not make payment in the current month, or never made a payment.
it is possible to do with a single query builder, or eloquent function?
With the code below I can do exactly the opposite of what I want :/
$indebted = DB::table('students')->where('students.active',1)
->leftJoin('payments', 'students.id', '=', 'payments.user_id')
->whereMonth('payments.created_at','=', $today->month)
->get();
I don't know what value you are passing here.
$today->month
Instead of this $today->month you have to pass exact month here
Please try this
$indebted = DB::table('students')->where('students.active',1)
->leftJoin('payments', 'students.id', '=', 'payments.user_id')
->whereMonth('payments.created_at','=', 06)
->get();
Here is the students ids who made payments in Current month and year
$payments= DB::table('payments')
->whereMonth('created_at',date('m'))
->whereYear('created_at', date('Y'))
->pluck('user_id')->all();
use whereNotIn('id',[students ids who made payments])
$students = DB::table('students')
->whereNotIn('id',$payments)
->get();
You can use Raw SQL in this kind of situation
I am assuming you are using mysql database
$sql=SELECT * from students s LEFT JOIN payments p ON s.id=p.user_id
WHERE s.active=1 AND (p.created_at is NULL or MONTH(MAX(p.created_at) < MONTH(CURRENT_DATE())) )
$students = DB::connection('mysql')->select( DB::raw(" $sql"));
foreach($students as $aStudent){
...
....
}
you can get student who do not have payments made in this month
$students = App\student::whereDoesntHave('payments', function (Builder $query) {
$query->whereMonth('payments.created_at',$today->month);
})->where('active',1)->get();

Return data ordered by date

I have a function that returns the count of sales each day. The problem with this approach is that I want the data to be stored by date but I am getting them in the following order:
01-Dec
02-Dec
03-Dec
03-Nov
04-Nov
05-Nov
etc.
I understand why that happens but I am not sure how to solve it. I can replace subMonth(1) with startofmonth which woul partially solve my problem but this is not what I want. I instead want to return the last 30 days ordered.
return DB::table('sales')
->select(\DB::RAW('DATE_FORMAT(created_at, "%d-%M") as date'), \DB::raw('COUNT(*) as count'))
->where('created_at', '>=', Carbon::now()->subMonth(1))
->orderBy('date')
->groupBy('date')
->get(['date', 'count'])
->keyBy('date')
->transform(function ($data) {
return $data->count;
});
I also tried orderBy('created_at') but it gives me the error below and I'd like to avoid changing the sql mode.
Syntax error or access violation: 1055 Expression #3 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'x.sales.created_at' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
EDIT:
As requested, this the sql query of the return statement
select DATE_FORMAT(created_at, "%d-%M") as date, COUNT(*) as count from `sales` where `created_at` >= ? group by `date` order by `date` asc
i don't have much idea about your framework query syntax. but you can take one more column DATE_FORMAT(created_at, "%Y%m%d") AS order_column and apply order, and group by on column "order_column" and use column "data" while display data.
select DATE_FORMAT(created_at, "%Y%m%d") AS order_column, DATE_FORMAT(created_at, "%d-%M") as date, COUNT(*) as count from `sales` where `created_at` >= ? group by `order_column` order by `order_column` asc
return DB::table('sales')
->select(\DB::RAW('DATE_FORMAT(created_at, "%Y%m%d") AS order_column'),\DB::RAW('DATE_FORMAT(created_at, "%d-%M") as date'), \DB::raw('COUNT(*) as count'))
->where('created_at', '>=', Carbon::now()->subMonth(1))
->orderBy('order_column')
->groupBy('order_column')
->get(['date', 'count'])
->keyBy('date')
->transform(function ($data) {
return $data->count;
});
If you make this in 2 steps does it work?
Step1 in which you create date column:
$step1 = DB::table('sales') ->select(\DB::RAW('DATE_FORMAT(created_at, "%d-%M") as date')))
->where('created_at', '>=', Carbon::now()->subMonth(1))
->orderBy('date')
->get(['date', 'count'])
and after that you make the agregation:
$step2 = $step1->select('date'), \DB::raw('COUNT(date) as count'))
->groupBy('date') ->get(['date', 'count']) ->keyBy('date')
Hope it helps!

Laravel 5.4 - Stats by month

I would like to count all the users who have the state "visible" and "ghost" like this :
public function getStatsUser() {
$data = self::whereIn('state', array('Visible', 'Ghost'))
->count();
return $data;
}
But i would like to have these data each month from the first user, like this :
['Month', 'Data'],
['December 2016', 4000],
['January 2017', 4600],
['February 2017', 11020],
['March 2017', 5400]
And for the date i have a row with "created_at" but not a specific row for the month.
I tried this, but it's not working
$data= self::select(DB::raw('count(*) as monthly_total'), DB::raw('MONTH(created_at) as month'))
->whereIn('state', array('visible', 'Ghost'))
->whereYear('created_at', '=', date('Y'))
->groupBy('month')
->count();
The error :
SQLSTATE[42S22]: Column not found: 1054 Champ 'month' inconnu dans group statement (SQL: select count(*) as aggregate from `oiseau` where `etat_actuel` in (Relaché, En convalescence) and year(`date_signalement`) = 2017 group by `month`)
Thanks for your help !
This should get you started:
self::selectRaw('CONCAT_WS(" ", MONTHNAME(created_at), YEAR(created_at)) as date, COUNT(*) as count')
->whereIn('state', array('visible', 'Ghost'))
->groupBy(DB::raw('YEAR(created_at)', MONTH(created_at)))
->get()
The query will return a Collection of objects with a date and a count.
Probably the most important part is to group by both the year and the month and you can use functions there instead of raw columns.
PS: This will get you Laravel Models from the self class, which they really aren't... so maybe replace the self with DB::table('users') or similar.
You can try like:
$data = self::whereIn('state', array('Visible', 'Ghost'))
->select(DB::raw('count(*) as monthly_total') , DB::raw('MONTH(created_at) month'))
->groupBy('month ')
->get();
Or try Join Query if Month is stored in other Table.

running a mysql query containing division in laravel 5

I want to run this mysql query in Laravel 5 using the DB query :
// SELECT *, rating/number as total FROM `courses` order by total DESC;
This is what I tried :
$query = \DB::table('courses')->select('*');
$courses = $query->addSelect('rating/number as total')
->orderBY('total DESC')
->get();
but, rating/number is considered as a table column . The same thing happens when I tried it inside parenthesis (rating/number).
Any help?
$courses = \DB::table('courses')
->selectRaw('*, rating/number as total')
->orderBY('total', 'DESC')
->get();
Can you use Raw Expressions for it? Maybe something like this:
$courses = \DB::table('courses')
->select(DB::raw('*, (rating / number) as total'))
->orderBy('total DESC')
->get();

Categories