I want to write this query in laravel 5.2
SELECT b.id,
TotalP,
b.booking_amount
FROM booking b
LEFT JOIN
(SELECT sum(amount) AS TotalP,
booking_id
FROM payment
GROUP BY booking_id) AS T ON b.id = T.booking_id
WHERE COALESCE(TotalP, 0) < b.booking_amount
My Question is related to this post.
I wrote a query after searching and studying but It is not working and need more constraint
$result = DB::table('my_booking')
->select('booking_name')
->leftJoin(DB::raw('(SELECT booking_id,sum(amount) as TotalP FROM `my_payment` GROUP BY booking_id) TotalPayment'), function($join)
{
$join->on('my_booking.id', '=', 'TotalPayment.booking_id');
})
->get();
Sql query to get data diffrence of total in 2 tables
You can try this,
$booking_payments = Booking::with('Payment')->find(1);
$total = 0;
foreach($booking_payments->payment as $booking_payment){
$total += $booking_payment->amount;
}
if($booking_payments->booking_amount == $total){
// if the total and booking_amount is equal
}
This should work in Laravel and give you the same exact result as your MySQL query. I moved COALESCE into the subquery select area so that you don't have to write a raw DB where statement in Laravel.
$sql_subquery = "(SELECT COALESCE(SUM(amount),0) AS TotalP,
booking_id
FROM payment
GROUP BY booking_id) AS T";
$result = DB::table('booking AS b')
->leftJoin(DB::raw($sql_subquery), 'b.id', '=', 'T.booking_id')
->where('T.TotalP','<', 'b.booking_amount')
->select('b.id','T.TotalP','b.booking_amount')
->get();
Related
how to left join table have been group, in my case is, table A have data account number and table B is transaction, i have to calculate and group by account number before joining into table A,
if in sql natife is like bellow
select name.account_no
,amount
from
ci_account_name name left join (
select account_no,currency_id,sum(amount) as amount from
ci_account_transaction
where status <> 'X' and store_id = 62242
group by account_no,currency_id
) as trans
on name.account_no = trans.account_no
that coding is working, but how to implement in laravel eloquent
i have try code bellow but there is error
public function reportShowZerro($data){
$return = $this->accountNameModel->select (['ci_account_name.*'
,'amount'
])
->leftJoin("
$this->model->select(['account_no','currency_id',\DB::raw('SUM(amount) amount')
])
->where('store_id',62242)
->where('status','<>','X')
->where('year',$data['year'])
->where('month',$data['month'])
->groupBy('account_no','currency_id')
) as trans",'ci_account_name.account_no','=','trans.account_no'
->whereIn('ci_account_name.store_id',[0,62242)
->get();
return $return;
}
public function reportWithModel($data){
return $this->accountNameModel->select([
'ci_account_name.*',
'trans.store_id as trans_store_id','currency_id','amount'
])->leftJoin(
\DB::raw('
(select account_no,currency_id,store_id,sum(amount) as amount from
ci_account_transaction
where status <> "X" and store_id = '.store()->id.'
and year = '.$data["year"].' and month = '.$data["month"].'
group by account_no,currency_id
) as trans
'),
'trans.account_no',
'=',
'ci_account_name.account_no'
)
->whereIn('ci_account_name.store_id',[0,store()->id])
->orderBy('ci_account_name.account_no')
->get();
}
I have an order table and an order_details table in my system.
Relationship between order table and order details table is one to many, means One order has many order details.
Now the problem is i am trying to filter the order with the quantity of items a that are stored in order_details table.
what i doing right know trying to access with whereHas
if ($request->has('quantity') && $request->quantity != null){
$query = $query->whereHas('orderDetails',function ($q) use ($request){
$q->whereRaw('SUM(Quantity) >= '.$request->quantity);
});
}
$orders = $query->orderBy('OrderID','desc')->get();
But it throws an error
General error: 1111 Invalid use of group function (SQL: select * from `orders` where `AddedToCart` = 0 and `PaymentSucceeded` = 1 and exists (select * from `order_details` where `orders`.`OrderID` = `order_details`.`OrderID` and SUM(Quantity) >= 12) order by `OrderID` desc)
I will be vary thankful if i get the solution
To be able to use sum function you need to group by data and as I see you are trying to group them by orderID.
An approach like this might help:
$ordersIDs = DB::table('orderDetails')
->groupBy('OrderID')
->havingRaw('SUM(Quantity)', '>=', 12)
->pluck('orderID')->toArray();
$orders = DB::table('orders')
->whereIn($ordersIDs)
->get();
The above code executes two SQL queries, you can mix them easily to make one.
Hope it helps.
I have a query to select data from multiple tables. How do I write its equivalent code in codeigniter.
See the query:
select *
from A inner join B on (A.ad_no=B.ad_no)
where B.ad_no in (select ad_no
from A
where $staff!='00:00' and $staff!='0:00')
order by B.ctype asc, B.cname asc,B.ad_no asc
I tried a query in codeigniter but its taking longer time to load the result.
You can try the following (i removed the $ sign from staff)
$query = $this->db
->select("*")
->from("A")
->join("B", "A.ad = B.ad_no")
->where("B.ad_no in (select ad_no from A where staff!='00:00' and staff!='0:00')",NULL, false)
->order_by("B.ctype", "ASC")
->order_by("B.cname", "ASC")
->order_by("B.ad_no", "ASC")
->get();
You get a generated output with the following statement
echo $this->db
->select("*")
->from("A")
->join("B", "A.ad = B.ad_no")
->where("B.ad_no in (select ad_no from A where staff!='00:00' and staff!='0:00')",NULL, false)
->order_by("B.ctype", "ASC")
->order_by("B.cname", "ASC")
->order_by("B.ad_no", "ASC")
->get_compiled_select();
get subquery library from https://github.com/NTICompass/CodeIgniter-Subqueries/edit/master/libraries/Subquery.php
try the following code
$this->db->select('*')->from('A');
$this->db->join('b','A.ad_no=B.ad_no','inner');
$sub = $this->subquery->start_subquery('where_in');
$sub->select('ad_no')->from('A')->where("staff!='00:00'")->where("staff!='0:00'");
$this->subquery->end_subquery('B.ad_no', TRUE);
$this->db->order_by('B.ctype','asc');
$this->db->order_by('B.cname','asc');
$this->db->order_by('B.ad_no','asc');
$query=$this->db->get();
I have a working query goes like this
SELECT s.name as status, q.name as quality, p.name process, count(*)
FROM plates
JOIN equipment_status_codes s on equipment_status_code_id = s.id
JOIN plate_qualities q on plate_quality_id = q.id
JOIN processes p on process_id = p.id WHERE project_id in
(SELECT id
from projects
WHERE name like 'SPIRIT')
GROUP BY s.name, q.name, p.name ASC with ROLLUP
This works just and returns results just fine.
Now I am trying to put this in laravel syntax, but having some difficulties.
So I was thinking something along these lines.
return Plate::select('equipment_status_codes.name as Status', 'plate_qualities.name as Quality', 'processes.name as Process')
->join('equipment_status_codes', 'plates.equipment_status_code_id', '=', 'equipment_status_codes.id')
->join('plate_qualities', 'plates.plate_quality_id', '=', 'plate_qualities.id')
->join('processes', 'plates.process_id', '=', 'processes.id')
->groupBy(DB::raw('equipment_status_code_id WITH ROLLUP'))
...
...
->get();
Would someone help out. Thanks in advance!
Update:
#Govind Samrow
I have tried this query. It works (with couple of small adjustment) But I am not getting the same results as the one I get when I run the sql query.
I included screen shots.
So when I run the sql query.
I get the following results.
When I run the laravel query.
return DB::table('plates')
->join('equipment_status_codes', 'equipment_status_code_id', '=', 'equipment_status_codes.id')
->join('plate_qualities', 'plate_quality_id', '=', 'plate_qualities.id')
->join('processes', 'process_id', '=', 'processes.id')
->whereRaw("project_id IN(SELECT id from projects WHERE name like 'SPIRIT')")
->select(DB::raw('equipment_status_codes.name as Status'), DB::raw('IFNULL(plate_qualities.name, NULL) as Quality'), DB::raw('IFNULL(processes.name, NULL) as process'), DB::raw("COUNT(*) as Total" ))
->groupBy(DB::raw('equipment_status_codes.name WITH ROLLUP', 'plate_qualities.name WITH ROLLUP', 'processes.name WITH ROLLUP', 'asc'))
->get();
I get the following.
Almost there, but I am not sure what's going on?! Any ideas?
Try following Query for Joining with where Condition
return Plate::select('equipment_status_codes.name as Status', 'plate_qualities.name as Quality', 'processes.name as Process')
->join('equipment_status_codes', 'plates.equipment_status_code_id', '=', 'equipment_status_codes.id')
->join('plate_qualities', 'plates.plate_quality_id', '=', 'plate_qualities.id')
->join('processes', function($join)
{
$join->on('plates.process_id', '=', 'processes.id')
->whereIn('project_id', DB::table('projects')->where('name','LIKE','SPIRIT')->select('id')->get()->toArray());
})
->groupBy(DB::raw('equipment_status_code_id WITH ROLLUP'))
->get();
Hope this will help.
Use whereRaw for sub query in where clause Try this:
DB::table('plates')
->join('equipment_status_codes', 'equipment_status_code_id', '=', 'equipment_status_codes.id')
->join('plate_qualities', 'plate_quality_id', '=', 'plate_qualities.id')
->join('processes', 'process_id', '=', 'processes.id')
->whereRaw("project_id IN(SELECT id from projects WHERE name like 'SPIRIT')")
->select('equipment_status_codes.name as status', 'plate_qualities.name as quality', 'q.name as quality', 'processes.name as Process', DB::raw("COUNT(*) as Total"))
->groupBy(DB::raw('equipment_status_codes.name, plate_qualities.name, processes.name ASC with ROLLUP'))->get();
Here is raw sql result of above that got with toSql():
select `equipment_status_codes`.`name` as `status`, `plate_qualities`.`name` as `quality`, `q`.`name` as `quality`,
`processes`.`name` as `Process`, COUNT(*) as Total from `plates`
inner join `equipment_status_codes` on `equipment_status_code_id` = `equipment_status_codes`.`id`
inner join `plate_qualities` on `plate_quality_id` = `plate_qualities`.`id`
inner join `processes` on `process_id` = `processes`.`id`
where project_id IN(SELECT id from projects WHERE name like 'SPIRIT')
group by equipment_status_codes.name, plate_qualities.name, processes.name ASC with ROLLUP
Note: You can use SQL output with $query->toSql() and then compare with your actual SQL query.
You may use the table method on the DB facade to begin a query. The table method returns a fluent query builder instance for the given table, allowing you to chain more constraints onto the query and then finally get the results using the get method:
Check its link and get knowladge for laravel query builder:-
https://laravel.com/docs/5.4/queries
I'm getting some unexpected results when running an Eloquent join query. I get two different results from using the exact same query. One running with DB::raw(), the second with Eloquent.
In the Eloquent query, the Users that matches the
where squad_user.leave_time >= seasons.start_time
are missing and will not be included in the result set. The users that matches the
or squad_user.leave is null
will be included, however.
That's the only difference in the results from the two queries. The raw query actually produces the desired result set.
What really puzzles me is, if I check the query logs, both Laravel's and MySQL, I get the exact same query when running both the raw and Eloquent query.
Raw query (the actual query i get from the query log when running the Eloquent query)
return \DB::select(\DB::raw('
select users.*
from users
inner join squad_user on users.id = squad_user.user_id
inner join seasons on squad_user.squad_id = seasons.squad_id
where squad_user.join_time <= seasons.end_time
and (squad_user.leave_time >= seasons.start_time or squad_user.leave_time is null)
and seasons.id = :seasonId
'),
['seasonId' => 3]
);
Eloquent query
return User::join('squad_user', 'users.id', '=', 'squad_user.user_id')
->join('seasons', 'squad_user.squad_id', '=', 'seasons.squad_id')
->where('squad_user.join_time', '<=', 'seasons.end_time')
->where(function ($query)
{
$query->where('squad_user.leave_time', '>=', 'seasons.start_time')
->orWhereNull('squad_user.leave_time');
})
->where('seasons.id', 3)
->get(['users.*']);
Laravel's Eloquent query log
select `users`.*
from `users`
inner join `squad_user` on `users`.`id` = `squad_user`.`user_id`
inner join `seasons` on `squad_user`.`squad_id` = `seasons`.`squad_id`
where `squad_user`.`join_time` <= seasons.end_time
and (`squad_user`.`leave_time` >= seasons.start_time or `squad_user`.`leave_time` is null)
and `seasons`.`id` = 3
{"bindings":["seasons.end_time","seasons.start_time",3],"time":0.38,"name":"mysql"}
MySQL's general_log on the Eloquent query
select `users`.*
from `users`
inner join `squad_user` on `users`.`id` = `squad_user`.`user_id`
inner join `seasons` on `squad_user`.`squad_id` = `seasons`.`squad_id`
where `squad_user`.`join_time` <= ?
and (`squad_user`.`leave_time` >= ? or `squad_user`.`leave_time` is null)
and `seasons`.`id` = ?
MySQL's general_log on the Raw query
select users.*
from users
inner join squad_user on users.id = squad_user.user_id
inner join seasons on squad_user.squad_id = seasons.squad_id
where squad_user.join_time <= seasons.end_time
and (squad_user.leave_time >= seasons.start_time or squad_user.leave_time is null)
and seasons.id = ?
I would appreciate any pointers here, as I am very lost.
where binds 3rd param and treats it usually as a string, unless you tell it not to by using raw statement. DB::raw or whereRaw will work for you:
return User::join('squad_user', 'users.id', '=', 'squad_user.user_id')
->join('seasons', 'squad_user.squad_id', '=', 'seasons.squad_id')
->where('squad_user.join_time', '<=', DB::raw('seasons.end_time'))
->where(function ($query)
{
$query->where('squad_user.leave_time', '>=', DB::raw('seasons.start_time'))
->orWhereNull('squad_user.leave_time');
})
->where('seasons.id', 3)
->get(['users.*']);
Since Laravel Verion 5.2 you can also use whereColumn to verify that two columns are equal (or pass a comparison operator to the method):
->whereColumn('squad_user.join_time', '<=', 'seasons.end_time')