Laravel join 3 tables 1 from different database. Query really slow - php

I have below code,
$resultsInCalls = DB::table('log')
->join('user_2 as user_old', 'log.agent', '=', 'user_old.sip_id')
->join('db2.abc as call_r', 'log.agent', '=', 'call_r.localParty')
->select('user_old.fname','user_old.lname','log.data2', 'log.callid', 'call_r.filename')
->whereDate('log.created', '=', date('Y-m-d')) // this day
->where('log.data2', '>=', '45')
->where('log.agent', '=', $id)
->where(function ($query) {
$query->where('event', '=', 'COMPLETEAGENT')
->orWhere('event', '=', 'COMPLETECALLER');
})
->inRandomOrder()
->take(5)
->get();
var_dump($resultsInCalls);
log and user_2 tables are from same DB.When I run this query it takes too much time. How to join this kind of tables in laravel.

Related

Laravel WHERE scope on JOIN

I am trying to get "shifts" and get all records I have,
But I join it with orders and run where on orders by delivery_date here "the shift" which has no orders erased
now I need to make the where only on orders and not affect on shifts
Shift::leftJoin('mt_plans', 'mt_plans.shift_id', '=', 'shifts.id')
->leftJoin('subscriptions', 'subscriptions.plan_id', '=', 'mt_plans.plan_id')
->join('orders', 'orders.subscription_id', '=', 'subscriptions.id')
->join('mt_order_details', 'mt_order_details.order_id', '=', 'orders.id')
->join('mt_item', 'mt_item.item_id', '=', 'mt_order_details.item_id')
->where('orders.delivery_date', $request->date)
->whereIn('orders.status', [OrderStatus::ACCEPTED, OrderStatus::ASSIGNED, OrderStatus::FAILED, OrderStatus::SUCCESSFUL])
->select([
'mt_item.item_id as meal_id',
'mt_item.en_name',
'mt_item.color',
'mt_item.label_number',
'shifts.id as shift_id',
'shifts.title',
'shifts.start_time',
'shifts.end_time',
'shifts.pickup_time'
])
->get();
You need a left join where your condition applies:
Shift::leftJoin('mt_plans', 'mt_plans.shift_id', '=', 'shifts.id')
->leftJoin('subscriptions', 'subscriptions.plan_id', '=', 'mt_plans.plan_id')
->leftJoin('orders', function($q) use($request) {
$q->on('orders.subscription_id', '=', 'subscriptions.id');
$q->where('orders.delivery_date', '=', $request->date);
})
->leftJoin('mt_order_details', 'mt_order_details.order_id', '=', 'orders.id')
->leftJoin('mt_item', 'mt_item.item_id', '=', 'mt_order_details.item_id')
->whereIn('orders.status', [OrderStatus::ACCEPTED, OrderStatus::ASSIGNED, OrderStatus::FAILED, OrderStatus::SUCCESSFUL])
->select([
'mt_item.item_id as meal_id',
'mt_item.en_name',
'mt_item.color',
'mt_item.label_number',
'shifts.id as shift_id',
'shifts.title',
'shifts.start_time',
'shifts.end_time',
'shifts.pickup_time'
])
->get();
Then you keep all "shifts" but join only order with delivery_date condition.
Keep in mind that it will retrieve all "shifts" where where condition applies. The orders will be null if doesn't match the id and delivery_date

Laravel: Query with where clause gone wrong

What I am trying to achieve is to allow teachers to import a student into different classes.
Note: A student can be multiple classes.
The problem is that when I show the list of students in a select dropdown it should return all students except for students that are not in this class (the class being the page that I am on, app.com/classes/5 for example).
$students = User::join('group_user', 'users.id', '=', 'group_user.user_id')
->role('student')
->where('group_user.group_id', '!=', $id)
->orderBy('users.name', 'asc')
->get();
This works and shows all students that are not in this specific class BUT if a student that's in this class and another class their name appears in the list and as duplicate names.
What can I do?
When MySQL's only_full_group_by mode is turned on, it means that strict ANSI SQL rules will apply when using GROUP BY
You should try to select fields from schema on which you can apply group by instead of select *.
$students = User::join('group_user', 'users.id', '=', 'group_user.user_id')
->role('student')
->where('group_user.group_id', '!=', $id)
->select('users.id', 'other fields you used')
->orderBy('users.name', 'ASC')
->groupBy('users.id')
->get();
Not IN is also useful in your case
User::select('fields you used')
->role('student')
->whereNotIn('id', DB::table('group_user')->where('group_id', $id)->pluck('user_id')) // $id = 5
->orderBy('name', 'ASC')
->get();
Modify your query to use distinct() like so;
$students = User::join('group_user', 'users.id', '=', 'group_user.user_id')
->role('student')
->where('group_user.group_id', '!=', $id)
->orderBy('users.name', 'ASC')
->distinct()
->get();
You could also groupBy('users.id')
$students = User::join('group_user', 'users.id', '=', 'group_user.user_id')
->role('student')
->where('group_user.group_id', '!=', $id)
->orderBy('users.name', 'ASC')
->groupBy('users.id')
->get();

Laravel Eloquent Complex Join Statement - specific example provided

I have the following raw SQL that I'm trying to convert into Eloquent form:
SELECT oe.eventID, oe.eventName, oet.etName, date_format(oe.eventStartDate, '%c/%d/%Y') as eventStartDate,
date_format(oe.eventEndDate, '%c/%d/%Y') AS eventEndDate
FROM `org-event` oe
JOIN `org-event_types` oet on oe.eventTypeID=oet.etID and oet.orgID=?
JOIN `event-registration` er on er.eventID = oe.eventID
WHERE (er.regStatus='Active' or er.regStatus='In Progress') AND personID=? AND oe.deleted_at is NULL
ORDER BY oe.eventStartDate DESC
I've crafted the following and I'm running into an error saying that '10' isn't a column. 10 is the value of $this->currentPerson->defaultOrgID
DB::table('org-event')
->join('org-event_types', function($join) {
$join->on('org-event_types.etID', '=', 'org-event.eventTypeID');
$join->on('org-event_types.orgID', '=', $this->currentPerson->defaultOrgID);
})->join('event-registration', 'event-registration.eventID', '=', 'org-event.eventID')
->where('event-registration.personID', '=', auth()->user()->id)
->where(function($w) {
$w->where('event-registration.regStatus', '=', 'Active')
->orWhere('event-registration.regStatus', '=', 'In Progress');
})
->select('org-event.eventID', 'eventName', 'etName', 'eventStartDate', 'eventEndDate')
->orderBy('org-event.eventStartDate')->get();
I dropped the deleted_at where clause because that's automatic using eloquent.
You have to join on the corresponding foreign key: oe.eventTypeID=oet.etID and then supply a where explaining what you want to filter your results by, i.e. ->where('orgID','=',$this->currentPerson->defaultOrgID).
DB::table('org-event')
->join('org-event_types', function($join) {
$join->on('org-event_types.etID', '=', 'org-event.eventTypeID');
$join->on('org-event_types.orgID', '=', 'org-event.eventTypeID')->where('orgID','=',$this->currentPerson->defaultOrgID);
})->join('event-registration', 'event-registration.eventID', '=', 'org-event.eventID')
->where('event-registration.personID', '=', auth()->user()->id)
->where(function($w) {
$w->where('event-registration.regStatus', '=', 'Active')
->orWhere('event-registration.regStatus', '=', 'In Progress');
})
->select('org-event.eventID', 'eventName', 'etName', 'eventStartDate', 'eventEndDate')
->orderBy('org-event.eventStartDate')->get();

Laravel/Eloquent query going wrong

I have two tables, one with users, one with the name of their document. The first table consists of two columns: id and username. The second one consists of three columns: id, userid and document_name.
Now, I'm trying to create a query in the controller. What should happen, ideally, is that if someone visits website.com/{documentname}, it displays the username of the owner. Also, this should only happen if the current logged in user is the owner of the document. However, this is proving more difficult than I imagined. As in, I can't see what I'm doing wrong.
Here's the query:
$user = DB::table('documents')
->join('users', function($join)
{
$join->on('users.id', '=', 'documents.userid')
->where('documents.userid', '=', Auth::id())
->where('documents.document_name', '=', $document_name);
})
->get();
**Try this query :**
$user = DB::table('documents')
->leftJoin('users', 'users.id', '=', 'documents.userid')
->where('documents.userid', '=', Auth::id())
->where('documents.document_name', '=', $document_name);
->get();
$document_name isn't in scope for the join function: you need to pass it through to the closure via use
$user = DB::table('documents')
->join('users', function($join) use ($document_name)
{
$join->on('users.id', '=', 'documents.userid')
->where('documents.userid', '=', Auth::id())
->where('documents.document_name', '=', $document_name);
})
->get();
EDIT
Because the WHERE conditions apply to the base table, and not to the JOIN:
$user = DB::table('documents')
->join('users', function($join) {
$join->on('users.id', '=', 'documents.userid')
})
->where('userid', '=', Auth::id())
->where('document_name', '=', $document_name);
->get();

Perform JOIN on three or four different tables in Laravel syntax

TABLES X(ID,A_ID)A(ID,B_ID),B(ID,C_ID),C(ID,D_ID)D(id,VALUE)
I want to retrieve the value of D table using laravel syntax on basis of X table Id and perform a JOIN with other tables.
Please post answers only in laravel syntax. In other format I can do. I am new to it so.
X::select('value')
->join('a', 'X.a_id', '=', 'a.id')
->join('b', 'a.b_id', '=', 'b.id')
->join('c', 'b.c_id', '=', 'c.id')
->join('d', 'c.d_id', '=', 'd.id')
->where('x.id', '=', $val)
->get();
But it is not working. please provide me proper solution. Right now I am using PHP logic to get the value, rather than optimise the query.
There are many ways, but this is the basic:
$rows = DB::table('shares')
->join('users', 'users.id', '=', 'shares.user_id')
->join('follows', 'follows.user_id', '=', 'users.id')
->where('follows.follower_id', '=', 3)
->get();
doc
Try this:
DB::table('X')
->join('a', 'X.a_id', '=', 'a.id')
->join('b', 'a.b_id', '=', 'b.id')
->join('c', 'b.c_id', '=', 'c.id')
->join('d', 'c.d_id', '=', 'd.id')
->select('D.value')
->where('x.id', '=', $val)
->get();
$result = X::select('a.value', 'd.*')
->join('a', 'x.a_id', '=', 'a.id')
->join('b', 'a.b_id', '=', 'b.id')
->join('c', 'b.c_id', '=', 'c.id')
->join('d', 'c.d_id', '=', 'd.id')
->where('x.id', '=', $val)
->get();
foreach ($result as $row) {
# code...
}

Categories