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();
Related
I am new to Laravel and trying to support an existing application that is in Laravel 5. I am trying to convert the following SQL to eloquent structure
SELECT s.id,
CONCAT(u.first_name, ' ', u.last_name) AS user_name,
u.avatar_location AS user_img,
s.employee_photo,
d.name AS department,
seg.name AS segment,
s.survey_title,
s.before_action,
s.before_picture,
s.action,
s.action_date,
s.after_action,
s.after_picture,
s.nominated,
s.awarded,
s.created_at,
s.updated_at,
(SELECT COUNT(1) FROM likes l WHERE l.survey_id = s.id) AS likes,
(SELECT COUNT(1) FROM likes l WHERE l.survey_id = s.id AND l.user_id = 5) AS UserLikes,
(SELECT COUNT(1) FROM comments c WHERE c.survey_id = s.id ) AS comments
FROM surveys s
JOIN departments d
ON s.department = d.id
JOIN segments seg
ON s.segment_id = seg.id
JOIN users u
ON s.user_id = u.id
WHERE s.status = 'Approved'
ORDER BY s.action_date DESC
LIMIT 20 OFFSET 20
I know enough Laravel to know that my basic start would probably be
$surveys = DB::table('surveys')
->join('departments', 'surveys.department', '=', 'departments.id')
->join('segments', 'surveys.segment_id', '=', 'segments.id')
->join('users', 'surveys.user_id', '=', 'users.id')
->where('surveys.status', 'Approved')
->orderBy('surveys.action_date')
->skip(20)-take(20)
->select(...)->get();
However, I am not sure how to do the subqueries. Looking for any suggestions.
Thanks!
For select statements, you can use DB::raw().
$surveys = DB::table('surveys')
->join('departments', 'surveys.department', '=', 'departments.id')
->join('segments', 'surveys.segment_id', '=', 'segments.id')
->join('users', 'surveys.user_id', '=', 'users.id')
->where('surveys.status', 'Approved')
->orderBy('surveys.action_date')
->skip(20)-take(20)
->select([DB::raw('(SELECT COUNT(1) FROM likes l WHERE l.survey_id = s.id) AS likes'),
...
])
->get();
Similarly, select statements would go under the select array. Just so to be clear, the result will be a collection.
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
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();
I have 3 tables: Users, Properties, Units
User table:
user_id user_name
Properties table
pty_id pty_name user pty_status
Units Table
unit_id unit_name pty_id unit_status
i want to show user details , number of properties and units and their details.
Here is my query:
DB::statement('SET SESSION group_concat_max_len = 10485760');
$ar = DB::table('users as u')
->leftjoin('properties as p', function($join) {
$join->on('p.user_id', '=', 'u.user_id')->where('p.pty_status', '!=' ,0 );
})
->leftJoin(
DB::raw("
(select COALESCE(count(unit_id),0) AS cntunits, pty_id as temp_pty
from property_units as pu3
left join properties as p2 on pu3.unit_pty_id = p2.pty_id
where pu3.unit_status!=0
group by p2.pty_id) as temp"), 'p.pty_id', '=', 'temp.temp_pty')
->select(
DB::raw("group_concat(DISTINCT CONCAT(ej_p.pty_id,'|',ej_p.pty_name,'|',cntunits)) as pty_details"),
DB::raw("group_concat(DISTINCT CONCAT(ej_p.pty_id,'|',ej_p.pty_name)) as pty_details_copy")
)->paginate(10);
When I group_concat the unit_count, only those properties and units are concated where unit exists.
For example the above query returns the following result:
pty_details pty_details_copy
7|I2|2 7|I2, 22|tR ,51|SG APARTMENT,54_||_GA APARTMENTS,
Why properties with units (where unit count=0) are not binding? Where have I gone wrong?
EDIT
Here is the raw query:
select group_concat(DISTINCT CONCAT(p.pty_id,'|',p.pty_name,'|',cntunits)) as pty_details,
group_concat(DISTINCT CONCAT(p.pty_id,'|',p.pty_name)) as pty_details_copy
from users as u
left join properties as p on p.user_id = u.user_id and p.pty_status !=0
left join
(select COALESCE(count(unit_id),0) AS cntunits, pty_id as temp_pty
from property_units as pu3
left join properties as p2 on pu3.unit_pty_id = p2.pty_id
where pu3.unit_status!=0
group by p2.pty_id) as temp on p.pty_id = temp.temp_pty
As Solarflare suggested, i got the required result when I changed the query like this:
$ar = DB::table('users as u')
->leftjoin('properties as p', function($join) {
$join->on('p.user_id', '=', 'u.user_id')->where('p.pty_status', '!=' ,0 );
})
->leftJoin(
DB::raw("
(select COALESCE(count(unit_id),0) AS cntunits, pty_id as temp_pty
from property_units as pu3
left join properties as p2 on pu3.unit_pty_id = p2.pty_id
where pu3.unit_status!=0
group by p2.pty_id) as temp"), 'p.pty_id', '=', 'temp.temp_pty')
->select(
DB::raw("group_concat(DISTINCT CONCAT(ej_p.pty_id,'|',ej_p.pty_name,'|',coalesce(cntunits, 0))) as pty_details"))->paginate(10);
The WHERE from your first join should be part of the ON.
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');
})