Converting large MySQL query to work with Laravel's DB - php

I have a very large query like so:
SELECT *
FROM cont_contracting
LEFT OUTER JOIN contacts_cont_contracting_1_c l1_1 ON cont_contracting.id=l1_1.contacts_cont_contracting_1cont_contracting_idb AND l1_1.deleted=0
LEFT OUTER JOIN contacts l1 ON l1.id=l1_1.contacts_cont_contracting_1contacts_ida AND l1.deleted=0
LEFT OUTER JOIN contacts_contacts_12_c l2_1 ON l1.id=l2_1.contacts_contacts_12contacts_ida AND l2_1.deleted=0
LEFT OUTER JOIN contacts l2 ON l2.id=l2_1.contacts_contacts_12contacts_idb AND l2.deleted=0
LEFT OUTER JOIN contacts_contacts_1_c l3_1 ON l1.id=l3_1.contacts_contacts_1contacts_ida AND l3_1.deleted=0
LEFT OUTER JOIN contacts l3 ON l3.id=l3_1.contacts_contacts_1contacts_idb AND l3.deleted=0
LEFT OUTER JOIN contacts_contacts_2_c l4_1 ON l1.id=l4_1.contacts_contacts_2contacts_ida AND l4_1.deleted=0
LEFT OUTER JOIN contacts l4 ON l4.id=l4_1.contacts_contacts_2contacts_idb AND l4.deleted=0
LEFT OUTER JOIN contacts_contacts_4_c l5_1 ON l1.id=l5_1.contacts_contacts_4contacts_ida AND l5_1.deleted=0
LEFT OUTER JOIN contacts l5 ON l5.id=l5_1.contacts_contacts_4contacts_idb AND l5.deleted=0
LEFT OUTER JOIN contacts_contacts_5_c l6_1 ON l1.id=l6_1.contacts_contacts_5contacts_ida AND l6_1.deleted=0
LEFT OUTER JOIN contacts l6 ON l6.id=l6_1.contacts_contacts_5contacts_idb AND l6.deleted=0
LEFT JOIN huge__insurance_carriers_cont_contracting_1_c l7_1 ON cont_contracting.id=l7_1.huge__insurance_carriers_cont_contracting_1cont_contracting_idb AND l7_1.deleted=0
LEFT JOIN huge__insurance_carriers l7 ON l7.id=l7_1.huge__insucae9arriers_ida AND l7.deleted=0
LEFT JOIN cont_contracting_cstm cont_contracting_cstm ON cont_contracting.id = cont_contracting_cstm.id_c
WHERE (((l1.id='b8a00721-40f1-7801-b4b9-50ce152ce2ec'
) OR (l2.id='b8a00721-40f1-7801-b4b9-50ce152ce2ec'
) OR (l3.id='b8a00721-40f1-7801-b4b9-50ce152ce2ec'
) OR (l4.id='b8a00721-40f1-7801-b4b9-50ce152ce2ec'
) OR (l5.id='b8a00721-40f1-7801-b4b9-50ce152ce2ec'
) OR (l6.id='b8a00721-40f1-7801-b4b9-50ce152ce2ec'
)))
I've been trying to convert this using Laravel's query builder, and this is what I've come up with but it's still not getting the data:
$appts = DB::table('cont_contracting')
->leftJoin('contacts_cont_contracting_1_c as l1_1', 'cont_contracting.id', '=', 'l1_1.contacts_cont_contracting_1cont_contracting_idb')
->leftJoin('contacts as l1', 'l1.id', '=', 'l1_1.contacts_cont_contracting_1contacts_ida')
->leftJoin('contacts_contacts_12_c as l2_1', 'l1.id', '=', 'l2_1.contacts_contacts_12contacts_ida')
->leftJoin('contacts as l2', 'l2.id', '=', 'l2_1.contacts_contacts_12contacts_idb')
->leftJoin('contacts_contacts_1_c as l3_1', 'l1.id', '=', 'l3_1.contacts_contacts_1contacts_ida')
->leftJoin('contacts as l3', 'l3.id', '=', 'l3_1.contacts_contacts_1contacts_idb')
->leftJoin('contacts_contacts_2_c as l4_1', 'l1.id', '=', 'l4_1.contacts_contacts_2contacts_ida')
->leftJoin('contacts as l4', 'l4.id', '=', 'l4_1.contacts_contacts_2contacts_idb')
->leftJoin('contacts_contacts_4_c as l5_1', 'l1.id', '=', 'l5_1.contacts_contacts_4contacts_ida')
->leftJoin('contacts as l5', 'l5.id', '=', 'l5_1.contacts_contacts_4contacts_idb')
->leftJoin('contacts_contacts_5_c as l6_1', 'l1.id', '=', 'l6_1.contacts_contacts_5contacts_ida')
->leftJoin('contacts as l6', 'l6.id', '=', 'l6_1.contacts_contacts_5contacts_idb')
->leftJoin('huge__insurance_carriers_cont_contracting_1_c as l7_1', 'cont_contracting.id', '=', 'l7_1.huge__insurance_carriers_cont_contracting_1cont_contracting_idb')
->leftJoin('huge__insurance_carriers as l7', 'l7.id', '=', 'l7_1.huge__insucae9arriers_ida')
->leftJoin('cont_contracting_cstm as cont_contracting_cstm', 'cont_contracting.id', '=', 'cont_contracting_cstm.id_c')
->where(function($query) {
$query->orWhere('l1.id', '=', Session::get('id'))
->orWhere('l2.id', '=', Session::get('id'))
->orWhere('l3.id', '=', Session::get('id'))
->orWhere('l4.id', '=', Session::get('id'))
->orWhere('l5.id', '=', Session::get('id'))
->orWhere('l6.id', '=', Session::get('id'));
})
->get();
What am I doing incorrectly that's causing the Laravel query to not be able to get the records properly?
I've checked the docs up and down multiple times and fail to see the problem.
Thanks

Related

Converting complex SQL select to Laravel Eloquent

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.

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 5.2 Advanced join with another join condition

so I'm building a query with the querybuilder where I need to count rows from a joined table that has a where condition from another table. I can't join that table in the end because it would result in the wrong rows being compared to this specific join. I thought the advanced join clausule would allow another join to be added in it's own scope but this seems to not be the case.
This is what I tried:
$profile = DB::table('users')
->select('users.username', 'users.profile_picture', 'users.screen_state',
'count(replies.id) as replies', 'count(interactions.id) as interactions',
'count(alerts.id) as alerts', 'count(user__followers.id) as followers',
'count(user__following.id) as following', 'count(following.id) as volgend')
->leftJoin('replies', function($join)
{
$join->on('users.id', '=', 'replies.user_id')
->leftJoin('alerts')
->on('replies.alert_id', '=', 'alerts.id')
->where('replies.user_id', '=', $user->id)
->where('alerts.hide', '=', 0);
})
->leftJoin('interactions', function($join)
{
$join->on('users.id', '=', 'interactions.user_id')
->leftJoin('alerts')
->on('interactions.alert_id', '=', 'alerts.id')
->where('interactions.user_id', '=', $user->id)
->where('alerts.hide', '=', 0);
})
->leftJoin('alerts', function($join)
{
$join->on('users.id', '=', 'alerts.user_id')
->where('alerts.user_id', '=', $user->id)
->where('alerts.hide', '=', 0);
})
->leftJoin('user__followers as user__following', function($join)
{
$join->on('users.id', '=', 'user__followers.user_id')
->where('user__followers.user_id', '=', $user->id)
->where('user__followers.follower_id', '=', $searchid);
})
->leftJoin('user__followers as following', function($join)
{
$join->on('users.id', '=', 'user__followers.user_id')
->where('user__followers.user_id', '=', $user->id);
})
->leftJoin('user__followers', function($join)
{
$join->on('users.id', '=', 'user__followers.user_id')
->where('user__followers.follower_id', '=', $user->id);
})
->where('users.id', '=', $user->id)
->get();
I also have this query in raw sql so you can see what I'm trying to achieve:
SELECT u.username, u.profile_picture, u.screen_state,
(SELECT count(DISTINCT r.id)
FROM `reply` r
LEFT JOIN alerts a
ON r.alert_id = a.alert_content_id
WHERE r.user_id = :userid AND a.hide=0)
AS replies,
(SELECT count(DISTINCT i.id)
FROM `interactions` i
LEFT JOIN alerts a
ON i.alert_id = a.alert_content_id
WHERE i.user_id = :userid AND a.hide=0)
AS interactions,
(SELECT count(DISTINCT a.alerts)
FROM `alerts` a
WHERE a.user_id = :userid AND a.hide=0)
AS alerts,
(SELECT count(DISTINCT uf.id)
FROM `user_followers` uf
WHERE uf.user_id = :userid
AND uf.follower_id = :searchid)
AS following,
(SELECT count(DISTINCT uf.id)
FROM `user_followers` uf
WHERE uf.user_id = :userid)
AS volgend,
(SELECT count(DISTINCT uf.id)
FROM `user_followers` uf
WHERE uf.follower_id = :userid)
AS followers
FROM users u
WHERE id = :userid GROUP BY id
But this gives me an error:
Call to undefined method Illuminate\Database\Query\JoinClause::leftJoin()
So my question is how can i join a table and check for a condition in yet another table?

I have this SQL query working and I want to migrate to the Laravel Query Builder format

Today is working with this SQL Query.
SELECT me.id
FROM refrees r
LEFT JOIN matches m
ON m.refree_id = r.id
LEFT JOIN match_events me
ON m.id = me.match_id
WHERE r.id = 1
AND me.match_event_type_id = 2
I have tried it, but its not working.
$c = DB::table('refrees as r')
->leftJoin('matches as m', 'r.id', '=', 'm.refree_id')
->leftJoin('match_events as me', 'me.id', '=', 'm.id')
->where('r.id', '=', '1')
->where('me.match_event_type_id', '=', '2')
->select('me.id')
->get();
The is a different condition in your second join.
LEFT JOIN match_events me m.id = me.match_id
have to be
->leftJoin('match_events as me', 'me.match_id', '=', 'm.id')
and not
->leftJoin('match_events as me', 'me.id', '=', 'm.id')
My bad. It was
->leftJoin('match_events as me', 'me.id', '=', 'm.id')
where I would put
->leftJoin('match_events as me', 'me.id_match', '=', 'm.id')

Laravel ORM query builder

I have the following interrogation that I want to translate into Laravel's Query Builder:
SELECT t.name, t.description, u.first_name as assignee_fname, u.last_name as assignee_lname,
us.first_name as reporter_fname, us.last_name as reporter_lname
FROM `tasks` AS t
LEFT JOIN `users` AS u
ON (t.asignee_id = u.id)
LEFT JOIN `users` AS us
ON (t.reporter_id = us.id);
Do you have any idea how can I do that?
Thank you
DB::table('tasks')->select('tasks.name', 'users.first_name AS assignee_fname', ...) //and the rest of your column
->leftJoin('users', 'taks.asignee_id', '=', 'users.id')
->leftJoin('users', 'tasks.reporter_id', '=', 'users.id')

Categories