Eloquent 2 left join query - sql

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)

Related

laravel where raw automaticaly add is null

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"));
})

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

Convert MariaDB SQL into Laravel Query

This is the working SQL in MariaDB:
SELECT * FROM ticket_categories
WHERE cat_name LIKE '%test%'
AND
( cat_parent_id = 236
OR cat_id = 236
OR cat_parent_id
IN (SELECT cat_id FROM ticket_categories Where cat_parent_id = 236)
)
What I have in Laravel Query so far:
$categoryList->where('ticket_categories.cat_name','like','%'.$request->input('name_filter').'%')
->where(function($query) use($request) {
query->where('ticket_categories.cat_parent_id', '=', $request->input('departments_filter'));
$query->orWhere('ticket_categories.cat_id','=', $request->input('departments_filter'));
$query->orWhereIn('ticket_categories.cat_parent_id', function($query1) use ($request) {
$query1->select('cat_id')
->from(with(new TicketCategory)->getTable())
->where('cat_parent_id', '=', $request->input('departments_filter'));
});
});
My code is now working but you can you can look for people's answer that is much cleaner.
First, I would rewrite your raw MariaDB query as follows:
SELECT *
FROM ticket_categories tc1
LEFT JOIN ticket_categories tc2
ON tc1.cat_parent_id = tc2.cat_id AND
tc2.cat_parent_id = 236
WHERE
tc1.cat_name LIKE '%test%' AND
(
tc1.cat_parent_id = 236 OR
tc1.cat_id = 236 OR
tc2.cat_id IS NOT NULL
);
This would correspond to the following Laravel code:
$results = DB::table('ticket_categories tc1')
->leftJoin('ticket_categories tc2', function($join) {
$join->on('tc1.cat_parent_id', '=', 'tc2.cat_i ');
$join->on('tc2.cat_parent_id', '=', 236);
->where('tc1.cat_name', 'like', '%test%')
->where(function($q) {
$q->where('tc1.cat_parent_id', 236)
->orWhere('tc1.cat_id', 236)
->OrWhereNotNull('tc2.cat_id')
})
->get();
Note that this answer assumes that a given category would have only one parent. If not, then my left join approach could generate duplicates. A workaround would be to use an EXISTS query in the WHERE clause.

Query with select and count in laravel

I did this Query in SQL but I can't make it work in Eloquent.
Please help me.
SELECT
tags.desc,
COUNT(planificacion_info.id_area) as cantidad_intervenciones
FROM
tags
INNER JOIN planificacion_info ON planificacion_info.id_area = tags.id_tag
WHERE
tags.grupo = 'area' and tags.estado = true
GROUP BY
tags.desc
You can do it like this :
$result = \DB::table('tags')->selectRaw('tags.desc, COUNT(planificacion_info.id_area) as cantidad_intervenciones')
->join('planificacion_info', 'planificacion_info.id_area', '=', 'tags.id_tag')
->where('tags.grupo', 'area')
->whereRaw('tags.estado = true')
->groupBy('tags.desc')
->get();
which gives you this request :
SELECT
tags.desc,
COUNT(planificacion_info.id_area) AS cantidad_intervenciones
FROM
`tags`
INNER JOIN `planificacion_info` ON `planificacion_info`.`id_area` = `tags`.`id_tag`
WHERE
`tags`.`grupo` = 'area'
AND tags.estado = TRUE
GROUP BY
`tags`.`desc`
Would be something liek this
$tags= DB::table('tags')
->select('tags.desc',DB::raw("COUNT(planificacion_info.id_area) AS cantidad_intervenciones")
->innerJoin('planificacion_info','planificacion_info.id_area','=','tags.id_tag')
->where('tags.grupo','area')
->where('tags.estado',true)
->groupBy('tags.desc')
->get();