subqueries in laravel 5.4 - php

how can I make this query to query builder laravel 5.4?
select * from gb_employee where employee_id not in (select gb_emp_client_empid from gb_emp_client_lines where gb_emp_client_clientid =1) ;

Use a left join for this
$employee=DB::table('gb_employee as e')
->select('e.*')
->leftJoin('gb_emp_client_lines as el', 'e.employee_id', '=', 'el.gb_emp_client_empid')
->whereNull('el.gb_emp_client_empid',)
->get()
;
doing via eloquent way
class Employee extends Model
{
public function client_lines()
{
return $this->hasMany('App\ClientLines', 'gb_emp_client_empid', 'employee_id');
}
}
$employees = Employee::doesntHave('client_lines')->get();

I think I solved it. . .
$employees = DB::table('gb_employee')
->whereNotIn('employee_id', function($query) use ($client_id)
{
$query->select('gb_emp_client_empid')
->from('gb_emp_client_lines')
->where('gb_emp_client_clientid',$client_id);
})
->get();

Related

Multiple Joins in Eloquent from local scopes

Got a question regarding Eloquent and the scope functionality:
Assuming two scopes:
class Result extends Model {
public function scopeIsRace($query) {
return $query
->join('sessions', 'sessions.id', '=', 'results.session_id')
->where('sessions.type', 10)
}
public function scopeIsOfficial($query) {
return $query
->join('sessions', 'sessions.id', '=', 'results.session_id')
->join('events', 'events.id', '=', 'sessions.event_id')
->where('events.regular_event', 1);
}
}
Calling both of them performs two joins of sessions and the resulting query looks sth like this (doesnt work)
select * from `results` inner join `sessions` on `sessions`.`id` = `results`.`session_id` inner join `sessions` on `sessions`.`id` = `results`.`session_id` inner join `events` on `events`.`id` = `sessions`.`event_id` where `driver_id` = 24 and (`sessions`.`type` = 10 or `sessions`.`type` = 11) and `events`.`regular_event` = 1
How do I prevent the double join on sessions?
Thank you so much #Nima. Totally forget about an advanced whereHas. Used a structure llke this from your suggested question and it works perfectly fine:
public function scopeIsRace($query) {
return $query->whereHas('session', function($query){
$query->where('type', 10);
});
}
public function scopeIsOfficial($query) {
return $query->whereHas('session', function($query) {
return $query->whereHas('event', function($query2) {
$query2->where('regular_event', 1);
});
});
}

How to apply where clause on field of related table on Laravel eloquent

I have following query that I need to achieve in Laravel eloquent:
SELECT Q.quoteid
FROM `tblquote` Q
INNER JOIN tbladdress A ON A.addressid = Q.addressid
INNER JOIN tblquotecompany QC ON QC.quoteid = Q.quoteid
INNER JOIN tblcompany C ON C.companyid = QC.companyid
WHERE
Q.useremail = 'test#test' or
(Q.ipaddress = '000.00.00.' and A.zipcode = '00000')
I have all relation set up in laravel.
I am trying to achieve this like below:
$this->eloquentQuote->newQuery()
->with(EloquentQuote::RELATION_ADDRESS)
->with(EloquentQuote::RELATION_QUOTE_COMPANIES . '.' . EloquentQuoteCompany::RELATION_COMPANY)
->whereHas(EloquentQuote::RELATION_ADDRESS,
function ($query) use ($userEmail, $userIp, $zipCode) {
/** #var Builder $query */
$query->where([
[EloquentQuote::USER_EMAIL, '=', $userEmail],
])
->orWhere([
[EloquentQuote::IP_ADDRESS, '=', $userIp],
[EloquentAddress::ZIP_CODE, '=', $zipCode],
]);
})->get();
This Eloquent query is giving expected result but taking too much time.
Is there any other way to do that efficiently?
Your help is highly regarded.
I hope the following code will be helpfull for you
$result = DB::table('tblquote')
->join('tbladdress', 'tbladdress.addressid', 'tblquote.addressid')
->join('tblquotecompany', 'tblquotecompany.quoteid', 'tblquote.quoteid')
->join('tblcompany', 'tblcompany.companyid', 'tblquotecompany.companyid')
->where('tblquote.useremail', 'test#test')
->orWhere([['tblquote.ipaddress','000.00.00.'], ['tbladdress.zipcode', '00000']])
->get();

Convert MySQL query to Laravel (5.5) Query Builder

I have a problem tying to convert the following MySQL query to the Laravel (5.5) Eloquent query builder.
$start = '2018-01-22'; // Some random starting point for the Query
$query = "SELECT * FROM cdr c WHERE soort=3 AND con_duur > 0 AND con_duur
>= (select kortbel_seconden from queue q where q.queue_id=c.queue_id) AND `start_tijd >= '$start'";`
I have the following Models:
// CDR Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class CDR extends Model
{
protected $table = 'cdr';
protected $primaryKey = 'cdr_id';
public function Queue()
{
return $this->hasOne('App\Models\Queue', 'queue_id', 'queue_id');
}
}
// Queue Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Queue extends Model
{
protected $table = 'queue';
protected $primaryKey = 'queue_id';
public function cdr()
{
return $this->belongsTo('App\Models\CDR', 'queue_id', 'queue_id');
}
}
So far I have the following code in my Controller:
App\Models\CDR::with('queue')
->where('soort', '3')
->where('con_duur', '>', '0')
->where('start_tijd', '>=' , $start)
->where('con_duur', '>=', ' ') // this is where the sub select from the `queue` table should be : (select kortbel_seconden from queue q where q.queue_id=c.queue_id)
->get();
I’m stuck at the point of the sub select, is there a way to do this with Laravel’s Query Builder?
Thanks!
Consider this code:
DB::table('cdr AS c')
->select("*")
->where('c.soort','=',3)
->where('c.con_duur','>',0)
->where('c.con_duur','>=',function($query){
$query->select('kortbel_seconden')
->from('queue AS q')
->where('q.queue_id', '=', 'c.queue_id');
})
->where("c.start_tijd",">=",$start)
->get();
This part of the query:
->where('c.con_duur','>=',function($query){
$query->select('kortbel_seconden')
->from('queue AS q')
->where('q.queue_id', '=', 'c.queue_id');
})
is used to achieve the below part of the query:
`c`.`con_duur` >=
(SELECT
kortbel_seconden
FROM
queue q
WHERE q.queue_id = c.queue_id)
The above query results can be achieved by the following query as well through join:
DB::table('cdr AS c')
->select("c.*")
->join('queue AS q', 'q.queue_id', '=', 'c.queue_id')
->where('c.soort','=',3)
->where('c.con_duur','>',0)
->where('c.con_duur','>=','q.kortbel_seconden')
->where("c.start_tijd",">=",$start)
->get();
For more details you can visit:
https://laravel.com/docs/5.5/queries#where-clauses

Laravel eloquent from DB

I have a very complicated db query, but I would like to know or is a possibility to short it and make it easier by eloquent?
My Model and his db is :
class Order extends Model
{
public $timestamps = false;
public $incrementing = false;
public function products()
{
return $this->hasMany(OrderProducts::class);
}
public function statuses()
{
return $this->belongsToMany(OrderStatusNames::class, 'order_statuses', 'order_id', 'status_id');
}
public function actualKioskOrders()
{
return
$rows = DB::select("SELECT o.id, o.number, o.name client_name, o.phone,
o.email, o.created_at order_date, osn.name actual_status
FROM orders o
JOIN order_statuses os ON os.order_id = o.id
JOIN (SELECT o.id id, MAX(os.created_at) last_status_date FROM orders o
JOIN order_statuses os ON os.order_id = o.id GROUP BY o.id) t
ON t.id = os.order_id AND t.last_status_date = os.created_at
JOIN order_status_names osn ON osn.id = os.status_id
WHERE os.status_id != 3");
}
}
Of course you can. Laravel query builder implements everything you need.
See Laravel Docs: Query Builder, it have join methods, where clause methods and select methods.
You can do for example the following:
Order::select(['id','number', 'name', 'client_name'])
->where('status_id', '!=', 3)
->join('order_statuses', 'order_statuses.order_id, '=', 'orders.id')
->get()
That's just an example on how you can create queries. Chain many methods that you need to create your query, the docs show many ways to do it, including with more complex joins if you need.

Laravel Eloquent: filtering model by relation table

I have places and locations tables.
Place could have many locations. Location belongs to Place.
Place:
id
title
Location:
id
place_id
floor
lat
lon
class Location extends Model {
public function place()
{
return $this->belongsTo('App\Place');
}
}
And
class Place extends Model {
public function locations()
{
return $this->hasMany('App\Location');
}
}
And i need to find places, that belongs only to 1st floor. select * from places inner join locations on places.id = locations.place_id where locations.floor = 1
How does it should be done in Eloquent?
Is something similar to
Place::where('locations.floor', '=', 1)->get() exists?
Yes, i know there is whereHas:
Place::whereHas('locations', function($q)
{
$q->where('floor', '=', 1);
})->get()
but it generates a bit complex query with counts:
select * from `places` where (select count(*) from `locations` where `locations`.`place_id` = `places`.`id` and `floor` = '1') >= 1
does not this works?
class Location extends Model {
public function place()
{
return $this->belongsTo('App\Place');
}
}
$locations = Location::where('floor', '=', 1);
$locations->load('place'); //lazy eager loading to reduce queries number
$locations->each(function($location){
$place = $location->place
//this will run for each found location
});
finally, any orm is not for database usage optimization, and it is not worth to expect nice sql's produced by it.
I haven't tried this, but you have eager loading and you can have a condition:
$places = Place::with(['locations' => function($query)
{
$query->where('floor', '=', 1);
}])->get();
Source
Try this :
Place::join('locations', 'places.id', '=', 'locations.place_id')
->where('locations.floor', 1)
->select('places.*')
->get();

Categories