Custom ways to write join, inner join mysql query in codeigniter - php

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

Related

How to convert raw SQL query to Laravel Query Builder

I need a following code to convert to Laravel query can any one help me with these.
SELECT id, `leave_name`, `total_leave_days`, leave_id, leave_taken_days FROM `leaves` AS t1 INNER JOIN ( SELECT leave_id, SUM(`leave_taken_days`) AS leave_taken_days FROM `leave_applications` WHERE user_id = 2 AND statuses_id = 2 GROUP BY leave_id ) AS t2 ON t1.id = t2.leave_id
I even tried but the output is not showing atall.
$user_leaves = DB::table('leaves')
->select('id', 'leave_name', 'total_leave_days', 'leave_id', 'leave_taken_days')
->join('leave_application', 'leave_application.leave_id', '=', 'leave.id')
->select('leave_application.leave_id', DB::raw("SUM(leave_taken_days) as leave_application.leave_taken_days"))
->where('user_id','=', 2)
->where('statuses_id','=', 2)
->get();
How can I solve this issue?
UPDATE
Relations between two models.
Leave Model
public function leave_application()
{
return $this->belongsTo(LeaveApplication::class, 'id' , 'leave_id');
}
Leave Application Model
public function leave()
{
return $this->belongsTo(Leave::class, 'leave_id', 'id');
}
Try this :
$user_leaves = Leave::select('leaves.id', 'leaves.leave_name', 'leaves.total_leave_days', 'leave_applications.leave_id', DB::raw('SUM(leave_applications.leave_taken_days) as leave_taken_days'))
->with('leave_application')
->whereHas('leave_application', function($q) {
$q->where('user_id', 2)
->where('statuses_id', 2);
})
->groupBy('leaves.id')
->get();
On this topic I would like to give my recommendations for some tools to help you out in the future.
SQL Statement to Laravel Eloquent to convert SQL to Laravel query builder. This does a decent job at low level queries. It also saves time when converting old code.
The other tool I use to view the query that is being run is Clock Work
I keep this open in a tab and monitor slow nasty queries or, also gives me perspective on how the query builder is writing SQL. If you have not use this extension I highly recommend getting and using it.
Actually I found my answer,
$user_leaves = DB::table('leaves as t1')
->select('t1.id', 't1.leave_name', 't1.total_leave_days', 't2.leave_id', 't2.leave_taken_days')
->join(DB::raw('(SELECT leave_id, SUM(leave_taken_days) AS leave_taken_days FROM leave_applications WHERE user_id = ' . $user_id . ' AND statuses_id = 2 GROUP BY leave_id) AS t2'), function ($join) {
$join->on('t1.id', '=', 't2.leave_id');
})
->get();
You can use DB:select("your query", params) and put your query and params (as an array (optional)
As below sample:
$result = DB:select("
SELECT id, `leave_name`, `total_leave_days`, leave_id, leave_taken_days
FROM `leaves` AS t1
INNER JOIN (
SELECT leave_id, SUM(`leave_taken_days`) AS leave_taken_days
FROM `leave_applications`
WHERE user_id = 2
AND statuses_id = 2
GROUP BY leave_id
) AS t2 ON t1.id = t2.leave_id" , $params
);
return response()->json($result);

Laravel: MYSQL query in laravel

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

MySQL query to Laravel Eloquent

I have the following MySQL query:
SELECT
*
FROM
news_posts
WHERE
user_id = ?
AND id NOT IN (SELECT
post_id
FROM
user_read
WHERE
user_id = ?)
I want to make it more "eloquent". I've tried the following, but its (obviously) not working:
NewsPost::where('user_id', Auth::id())
->whereNotIn(function ($query) {
$query->DB::table('user_read')
->select('post_id')
->where('user_id', Auth::id());
})->get();
I'm assuming the 'where' method is executing a simple SQL query on 'new_posts' table. Can you try to rewrite this query and let mysql do the filtering for new posts? (search for LEFT OUTER JOIN on mysql)
SELECT *
FROM news_posts a
JOIN user_read b
ON a.id = b.post_id
WHERE a.user_id = ?
AND b.post_id IS NULL;
Thanks for all the replies! Got it working with the following tweaks:
NewsPost::where('user_id', Auth::id())
->whereNotIn('id', function ($query) {
$query->select('post_id')
->from('user_read')
->where('user_id', Auth::id());
})
->get();

Laravel subquery

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

Codeigniter Active Record / MySQL Join Query - How to Return Results if one of the Table Rows is Not Present

I have the following query:
$this->db
->select('SQL_CALC_FOUND_ROWS null as rows
,table1.*
,table2.*
,table3.*', FALSE)
->from('table1')
->where('table1.column1', $user_id)
->join('table2', 'table2.column2 = table1.column2')
->join('table3', 'table3.column2 = table1.column2')
->group_by('table1.column2')
->order_by('table1.column2', 'DESC');
$query = $this->db->get();
The problem is, there may not be a row in table 3 and if there is not, I would still like to return a result with the remainder of the query data. Please could someone advise how to achieve this?
you should do a left join on table3
Use left join and also use group_by to get exact records:
$this->db->join('login_ranknames AS t4', 't4.id = t1.rank', 'left');
$this->db->group_by('t4.id');

Categories