laravel where raw automaticaly add is null - sql

i have this code where i need to join transactions with transaction_sell_lines and transactions with purchase_lines. Then purchase_lines and transaction_sell_lines both has variation_id. I need to join those variation_id to variations table.
Transaction::leftJoin('purchase_lines as pl', 'transactions.id', '=', 'pl.transaction_id')
->leftJoin('transaction_sell_lines as sl', 'transactions.id', '=', 'sl.transaction_id')
->join('variations as v', function ($query) {
$query->where(DB::raw("CONCAT(COALESCE(sl.variation_id, ''), COALESCE(pl.variation_id, ''))"));
}, '=', 'v.id')
and when i checked the query using DB::enableQueryLog(); for some reason laravel automatically add is null even though i did not mention it anywhere. i could use whereNotNull() but the result still are not the same. the code could be seen below
from `transactions` left join `purchase_lines` as `pl` on `transactions`.`id` = `pl`.`transaction_id`
left join `transaction_sell_lines` as `sl` on `transactions`.`id` = `sl`.`transaction_id`
inner join `variations` as `v` on CONCAT(COALESCE(sl.variation_id, ''), COALESCE(pl.variation_id, '')) is null
how do i achieve this sql
from transactions LEFT JOIN purchase_lines as pl on pl.transaction_id = transactions.id
LEFT JOIN transaction_sell_lines as sl ON sl.transaction_id = transactions.id
LEFT JOIN variations as v on v.id = CONCAT(COALESCE(sl.variation_id,''),COALESCE(pl.variation_id,''))

I would suggest that you replace
$query->where(DB::raw("...")
with the whereRaw-function instead:
Transaction::leftJoin('purchase_lines as pl', 'transactions.id', '=', 'pl.transaction_id')
->leftJoin('transaction_sell_lines as sl', 'transactions.id', '=', 'sl.transaction_id')
->join('variations as v', function ($query) {
$query->whereRaw("CONCAT(COALESCE(sl.variation_id, ''), COALESCE(pl.variation_id, ''))");
}, '=', 'v.id')

you are using Advanced Join Clauses the wrong way ...
join with closure should take a Illuminate\Database\Query\JoinClause instance which allows you to specify constraints on the "join" clause, so the constraints should be in that function:
you can replace:
->join('variations as v', function ($query) {
$query->where(DB::raw("CONCAT(COALESCE(sl.variation_id, ''), COALESCE(pl.variation_id, ''))"));
}, '=', 'v.id')
with:
->join('variations as v', function ($query) {
$query->where(DB::raw("CONCAT(COALESCE(sl.variation_id, ''), COALESCE(pl.variation_id, ''))=v.id"));
})

Related

Eloquent select with join and not exists in raw statement

I need to write select statement like that:
SELECT co.id FROM client_order co
INNER JOIN client_order_status cos ON cos.id = co.order_status_id AND cos.name IN ('for_shipping', 'to_be_shipped_later')
WHERE NOT EXISTS (SELECT 1 FROM dpackage dp WHERE dp.order_id = co.id AND dp.is_spec_label_generated = 1)
ORDER BY co.id
In Eloquent my expression looks like that:
$clientOrderEntities = ClientOrder::join('client_order_status', 'client_order_status.id', '=', 'order_status_id')
->whereIn('client_order_status.name', ['for_shipping', 'to_be_shipped_later'])
->whereNotExists(function($query) use($orderId) {
$query->select(DB::raw(1))
->from('dpackage')
->where([
['order_id', '=', $orderId]
['is_spec_label_generated', '=', 1]
]);
})->get();
I don't know how to pass orderId from first part of query into whereNotExists sub query
At the moment it looks:
$clientOrderEntities = ClientOrder::join('client_order_status', 'client_order_status.id', '=', 'order_status_id')
->whereIn('client_order_status.name', ['for_shipping', 'to_be_shipped_later'])
->whereNotExists(function($query) {
$query->select(DB::raw(1))
->from('dpackage')
->where([
['order_id', '=', 'client_order.id'],
['is_spec_label_generated', '=', 1]
]);
})
->select('client_order.*')
->get();
This query works:
$clientOrderEntities = ClientOrder::join('client_order_status', 'client_order_status.id', '=', 'order_status_id')
->whereIn('client_order_status.name', ['for_shipping', 'to_be_shipped_later'])
->whereRaw(' NOT EXISTS (SELECT 1 FROM dpackage dp WHERE dp.order_id = client_order.id AND dp.is_spec_label_generated = 1) ')
->select('client_order.*')
->get();
This query works too and is faster than eloquent statements, as #Newbie wrotes, but I don't know why his answer has been deleted:
$clientOrderEntities = DB::select('SELECT co.* FROM client_order co INNER JOIN client_order_status cos ON cos.id = co.order_status_id AND cos.name IN ("for_shipping", "to_be_shipped_later") WHERE NOT EXISTS (SELECT 1 FROM dpackage dp WHERE dp.order_id = co.id AND dp.is_spec_label_generated = 1) ');
Maybe defining name for the tables help you with this.
$clientOrderEntities = \DB::table('client_order as co')
->join('client_order_status as cos', 'cos.id', '=', 'co.order_status_id')
->whereIn('cos.name', ['for_shipping', 'to_be_shipped_later'])
->whereNotExists(function($query) {
$query->select(DB::raw(1))
->from('dpackage')
->where([
['order_id', '=', 'co.id'],
['is_spec_label_generated', '=', 1]
]);
})->get();

Convert SQL with nested queries to Laravel Eloquent

I need to convert this query that I got from Access to an Laravel eloquent for my remake database project, and this is what i did but i haven't the same result with the origin sql thanks.
SELECT T_Sites.Code_Region, T_Sites.Nom_Site, T_CLM.N_CLM, T_Port.N_Port,
T_Vlan.IP_Vlan, T_Ref_Vlan.Id_Referentiel, T_Ref_Vlan.Nom_Vlan,
T_Vlan.Dt_Creat, T_Vlan.Id_Vlan, T_Vlan.IP_HSRP, T_Vlan.IP_SousReseaux,
T_CLM.Id_CLM, T_Vlan.Masque
FROM (T_CLM
INNER JOIN (
(T_Port INNER JOIN T_Vlan ON T_Port.Id_Port = T_Vlan.Id_Port)
LEFT JOIN T_Ref_Vlan ON T_Vlan.Id_Referentiel = T_Ref_Vlan.Id_Referentiel
)
ON T_CLM.Id_CLM = T_Port.Id_CLM)
INNER JOIN T_Sites ON T_CLM.Id_Site = T_Sites.Id_Site
ORDER BY T_CLM.Id_CLM DESC
WITH OWNERACCESS OPTION;
// what i did
$SuiviVlan = DB::table('T_CLM')
->join('T_Sites', 'T_CLM.Id_Site', '=', 'T_Sites.Id_Site')
->join('T_Port', 'T_CLM.Id_CLM' , '=', 'T_Port.Id_CLM')
->join('T_Vlan', 'T_Vlan.Id_Port', '=', 'T_Port.Id_Port')
->leftjoin('T_Ref_Vlan', 'T_Ref_Vlan.Id_Referentiel', '=', 'T_Vlan.Id_Referentiel')
->select('T_Sites.Code_Region','T_Sites.Nom_Site','T_CLM.N_CLM','T_Port.N_Port','T_Vlan.IP_Vlan',
'T_Ref_Vlan.Id_Referentiel', 'T_Ref_Vlan.Nom_Vlan', 'T_Vlan.Dt_Creat', 'T_Vlan.Id_Vlan', 'T_Vlan.IP_HSRP',
'T_Vlan.IP_SousReseaux', 'T_CLM.Id_CLM', 'T_Vlan.Masque')
->orderBy('T_CLM.Id_CLM', 'desc')
->get();
// It was the correct laravel eloquent , thanks btw for help.
$SuiviVlan = DB::table('T_CLM')
->join('T_Sites', 'T_CLM.Id_Site', '=', 'T_Sites.Id_Site')
->join('T_Port', 'T_CLM.Id_CLM' , '=', 'T_Port.Id_CLM')
->join('T_Vlan', 'T_Vlan.Id_Port', '=', 'T_Port.Id_Port')
->leftjoin('T_Ref_Vlan', 'T_Ref_Vlan.Id_Referentiel', '=', 'T_Vlan.Id_Referentiel')
->select('T_Sites.Code_Region','T_Sites.Nom_Site','T_CLM.N_CLM','T_Port.N_Port','T_Vlan.IP_Vlan',
'T_Ref_Vlan.Id_Referentiel', 'T_Ref_Vlan.Nom_Vlan', 'T_Vlan.Dt_Creat', 'T_Vlan.Id_Vlan', 'T_Vlan.IP_HSRP',
'T_Vlan.IP_SousReseaux', 'T_CLM.Id_CLM', 'T_Vlan.Masque')
->orderBy('T_CLM.Id_CLM', 'desc')
->get();

Eloquent 2 left join query

I would like to execute the following query using Laravel's eloquent query builder:
SELECT a.*, b.day, c.sex FROM hours as a
left join reserves as b
on a.id = b.hour_id and b.day = '2015-12-12'
left join doctors as c
on a.doctor_id = c.id
where a.doctor_id = 1;
I have tried the following:
Hour::leftJoin('reserves', function($join) {
$join->on('hours.id' , '=' , 'reserves.hour_id')
->where('reserves.day' , '=' , '2015-12-12');
})
->leftJoin('doctors', function($join) {
$join->on('hours.doctor_id', '=', 'doctors.id');
})
->where('hours.doctor_id', '=', $doctorId)
->get();
Unfortunately, I am not getting the same results.
Everything looks fine, however you miss selecting columns, after Hour:: you should add:
select('hours.*'.'reserves.day','doctors.sex')->
You could also make second join simpler and use aliases, so the final code could look like this:
Hour::select('hours.*'.'reserves.day','doctors.sex')
->from('hours AS a')
->leftJoin('reserves AS b', function($join) {
$join->on('a.id' , '=' , 'b.hour_id')
->where('b.day' , '2015-12-12');
})
->leftJoin('doctors AS c', 'a.doctor_id', '=', 'c.id')
->where('a.doctor_id', $doctorId)
->get();
Of course as $doctorId you should set 1 to get exact same result
you can use DB::raw :
Hour::select(DB::raw('hours.*'),reserves.day, c.doctors)
->leftJoin('reserves',DB::raw("hours.id = reserves.hour_id AND reserves.day='2015-12-12'") ,DB::raw(''), DB::raw(''))
->leftJoin('doctors','hours.doctor_id', '=', 'doctors.id')
->where('hours.doctor_id', '=', $doctorId)
->get()
the 2 empty DB::raw is because leftJoin expect 4 arguments(table,columnA,operator,columnB)

Eloquent advanced where within an advanced join

I'm trying to do the following join:
Schedules::select()
->leftJoin('histories', function ($j)
{
$j->on('histories.schedule_id', '=', 'schedules.id')
->where('histories.test', '=', DB::raw('schedules.test'))
->where(function ($q)
{
$q->where('histories.order_id', '=', 'schedules.order_id')
->orWhere('histories.customer_id', '=', DB::raw('schedules.customer_id'));
});
});
When I do, Laravel reports the error:
Missing argument 2 for Illuminate\Database\Query\JoinClause::where()
How do I structure this query in Eloquent syntax so that I get the equivalent of the following for the join statement?
left join histories
on histories.schedule_id = schedules.id
and histories.test = schedules.test
and (
histories.order_id = schedules.order_id
or histories.customer_id = schedules.customer_id
)
Unfortunately JoinClauses where doesn't work like ordinary where clause, and you can't pass closure for nested wheres, so you just need to repeat part of your conditions.
Also, you don't need where and DB::raw for your additional join clauses, instead use on once again.
So basically you need this:
$j->on('histories.schedule_id', '=', 'schedules.id')
->on('histories.test', '=', 'schedules.test')
->on('histories.order_id', '=', 'schedules.order_id')
->orOn('histories.schedule_id', '=', 'schedules.id')
->on('histories.test', '=', 'schedules.test')
->on('histories.customer_id', '=', 'schedules.customer_id');

Multi join select query on Laravel

How to write this query in Laravel. I am new in laravel.
Example:
SELECT * FROM ((respassanger join ((`reservation` join flightres
on flightres.res_id = reservation.id)) on respassanger.res_id = reservation.id)
join passanger on respassanger.pas_id = passanger.pas_id)
Have you read the documentation? Checkout Laravel's query builder. Using your table names as mentioned, work from the following example in the docs for your needs:
DB::table('users')
->join('contacts', function($join)
{
$join->on('users.id', '=', 'contacts.user_id')->orOn(...);
})
->get();
So something like:
DB::table('respassanger')
->join('reservation', function($join)
{
$join->on('flightres.res_id', '=', 'reservation.id')
})
->join('passanger', 'respassanger.pas_id', '=', 'passanger.pas_id')
->select( ... )
->get();
Not sure how correct the above is, but tweak it if it doesn't work.