Laravel 5.3 Eloquent Join table with multiple condition join having count - php

I have question about left join table which using having count to select main table to be shown with the condition described as below:
select b.id, b.location_name, b.box_identity
from box b
left join device d on b.id = d.box_id
and d.deleted_at is null
group by b.id, b.location_name, b.box_identity
having count(d.*) < COALESCE(b.device_slot, 3)
order by b.id desc
i have tried using eloquent code like this, but DB::raw is not working in $join function
$boxes = Box::leftJoin('device', function($join) {
$join->on('box.id', '=', 'device.box_id');
$join->on(DB::raw('device.deleted_at is null'));
})
->select('box.id', 'box.box_identity', 'box.location_name')
->groupBy('box.id', 'box.box_identity', 'box.location_name')
->havingRaw('COUNT(device.*) < COALESCE(box.device_slot, 3)')
->orderBy('box.id', 'desc')
->get();
How can i achieve this query using laravel eloquent? Thanks in advance!

use this :
$boxes = Box::leftJoin('device', function($join) {
$join->on('box.id', '=', 'device.box_id');
$join->whereRaw('device.deleted_at is null');
})

Related

Laravel 6, MYSQL - How to Left Join a Sub Query with GroupBY using Laravel Querybuilder or Model Eloquent?

Im tried this to work it using Laravel Eloquent but i cant get exact query. So i make a raw query to get the data i want. Any one help me how to convert this into laravel eloquent or Query builder?
SELECT users.*,
chat.*
FROM users
LEFT JOIN
(SELECT a.customer_id,
a.time,
b.content
FROM
(SELECT customer_id,
MAX(datetimestamp) TIME
FROM chat_messages
GROUP BY customer_id) a
JOIN chat_messages b ON a.customer_id = b.customer_id
AND a.time = b.datetimestamp) chat ON users.id = chat.customer_id
WHERE users.customer_role != 0
ORDER BY TIME DESC
I think you are trying to get latest chat message for each user , your query can be rewritten using left join to pick the latest record per group and it would be easier to transform such query in laravel's query builder format
SQL
select u.*,c.*
from users u
join chat_messages c on u.id = c.customer_id
left join chat_messages c1 on c.customer_id = c1.customer_id and c.datetimestamp < c1.datetimestamp
where c1.customer_id is null
and u.customer_role != 0
order by c.datetimestamp desc
Query Builder
DB::table('users as u')
->select('u.*, c.*')
->join('chat_messages as c', 'u.id', '=', 'c.customer_id' )
->leftJoin('chat_messages as c1', function ($join) {
$join->on('c.customer_id', '=', 'c1.customer_id')
->whereRaw(DB::raw('c.datetimestamp < c1.datetimestamp'));
})
->whereNull('c1.customer_id')
->where('u.customer_role','!=',0)
->orderBy('c.datetimestamp', 'desc')
->get();
Reference:Laravel Eloquent select all rows with max created_at

How to convert a specific PostgreSQL query to laravel query builder

Im trying to convert a postgresql query to the laravel query builder style.
I have almost no experience with the laravel query builder. I dont want to use the DB raw.
SELECT ca1.component, ca1.previousfeeder, COUNT(ca1.previousfeeder)
FROM mydbcarrdata_10.carrier ca1
WHERE ca1.component IN (
SELECT e.articlename
FROM mydbcarrdata_10.carrier ca
JOIN mydbcompdata_10.component co
ON ca.component = co.name
JOIN mydbmanldata_10.entry e
ON e.articlename = co.name
JOIN mydbmanldata_10.header h
ON h.id = e.headerid
JOIN mydbmanldata_10.mandata m
ON h.layoutid = m.id
JOIN mydblytldata_10.layout l
ON m.layout = l.name
WHERE l.name = 'M2077F_bottom'
GROUP BY e.articlename
)
GROUP BY ca1.component, ca1.previousfeeder
ORDER BY ca1.component asc
Ive found the corresponding query using the query builder:
DB::table('mydbcarrdata_10.carrier')->select(DB::raw('component, previousfeeder, count(previousfeeder)'))
->whereIn('component', DB::table('mydbcarrdata_10.carrier')->select('articlename')
->join('mydbcompdata_10.component', 'component.name', '=', 'carrier.component')
->join('mydbmanldata_10.entry', 'component.name', '=', 'entry.articlename')
->join('mydbmanldata_10.header', 'entry.headerid', '=', 'header.id')
->join('mydbmanldata_10.mandata', 'mandata.id', '=', 'header.layoutid')
->join('mydblytldata_10.layout', 'layout.name', '=', 'mandata.layout')
->where('layout.name', '=', 'M2077F_bottom')
->groupBy('entry.articlename')
->pluck('articlename')
)
->groupBy('component', 'previousfeeder')
->orderBy('component', 'asc')
->get();

What is the equivalent of this MySQL query to Laravel Query Builder?

This is my query from MySQL. I want to use 'LEFT JOIN' to two same tables with different aliases and having an 'ON' that has 'AND' inside its parenthesis. And this query arrives with the correct results, but my problem is how can I know the equivalent of this query to its Laravel query?
SELECT * FROM table1 AS a
LEFT JOIN table1 AS b
ON (a.column1 = b.column1 AND a.column2 < b.column2)
WHERE b.column2 is null;
And then I use this query in Laravel Query Builder which will query the wrong results.
DB::table('table1 As a')
->leftJoin('table1 As b', 'a.column1', '=', 'b.column1')
->leftJoin('table2 As c','a.column2', '<', 'c.column2')
->whereNull('c.column2')
->get();
This Laravel query is equivalent to this MySQL query which will, unfortunately, query the same wrong results:
SELECT * FROM table1 AS a
LEFT JOIN table1 AS b
ON (a.column1 = b.column1 AND )
LEFT JOIN table1 AS c
ON (a.column2 < c.column2)
WHERE b.column2 is null;
You need to pass a function to the leftJoin() Something like this...
DB::table('table1 as a')
->leftJoin('table1 as b', function($join) {
return $join->on('a.column1', '=', 'b.column1')
->whereColumn('a.column2', '<', 'b.column2');
})->get();

laravel - inner join query for three tables

I want to join department d table with department dl table and user u table. I have done this in SQL query.
SELECT distinct(dl.head),
u.user_name,
u.id
from department d
inner join department dl on d.parent_department_string_id=dl.string_id
inner join users u on dl.head=u.user_name
where d.sl_flag=1
I want to do the same in Laravel query. Is it possible to join the same table using join in Laravel?
You can try something like this.
$departmentData = DB::table('department AS d')
->innerJoin('department AS d1', function($join) {
$join->on('d.parent_department_string_id', '=', 'd1.string_id');
})
->innerJoin('users AS u', function($userJoin) {
$userJoin->on('d1.head', '=', 'u.user_name');
})
->where('d.sl_flag', '=', 1)
->select(\DB::raw('distinct(dl.head) AS head'), 'u.user_name', 'u.id')
->get();

Laravel: left join query

I have such SQL query, which works fine:
SELECT A.program_id FROM A
LEFT JOIN B
ON A.program_id = B.program_id
WHERE
B.program_id IS NULL
But i want it to rewrite into LARAVEL style, like this:
\DB::table('A')
->join('B', 'A.program_id', '=', 'B.program_id')
->select('A.program_id')
->whereNull('B.program_id')
->get()->toArray();
But this code returns me 0 results.
You are using join instead of left join
Try this
\DB::table('A')
->leftjoin('B', 'A.program_id', '=', 'B.program_id')
->select('A.program_id')
->whereNull('B.program_id')
->where('A.student_id', '=', 5)
->get()->toArray();
It will produce a query like

Categories