i use laravel datatables serverside to get data from 4 tables and display them.
The code that i have on routes/web.php is:
Route::get('/serverSideSymv', [
'as' => 'serverSideSymv',
'uses' => function () {
$symv = App\Symvolaia::Select('table1.*')
->join('table2', 'table1.field1', '=', 'table2.id')
->join('table3', 'table1.field2', '=', 'table3.id')
->leftJoin('table4', function($join)
{
$join->on('table1.field3', '=', 'table4.field5');
$join->on('table1.field6', '=', 'table4.field7');
})
->select('table1.id','table2.field1','table1.field2','table1.field3','table1.field4','table3.field5','table1.field6','table1.field7','table1.field8','table4.field9','table1.field10','table1.field11','table1.field12','table1.field13','table1.field14','table2.field15');
return Datatables::of($symv)
->editColumn('field5', function($data) {
return Illuminate\Support\Facades\Crypt::decrypt($data->field5);
})
->make();
}
]);
The issue is that the main table (Table1) has more than 20.000 records and will have much more. I get max execution time exceeded. Is there any way to optimize the query or somehow show the results in datatables?
Related
Good day, I'm trying to get orders with products that have a specific products progress.
My Laravel query looks like this:
return Order::whereHas('products.progress', function (Builder $query) {
$query->where('progress_id', 100)
->orWhereBetween('progress_id', [160, 240]);
})
->with('products.progress')
->select('orders.id', 'orders.customer_id', 'orders.created_at')
->get();
In the query I set a where and whereBetween, the last Product has the progress_id 50 that one should not be loaded into the order.
How to do it? Thank you for reading.
i think you want to Constraining Eager Loads
so your (wheres) should be on the loading ...
return Order::with(['products'=>function($query){
$query->whereHas('progress',function ($query){
$query->where('progress_id', 100)
->orWhereBetween('progress_id', [160, 240]);
})->with('progress');
}])
->select('orders.id', 'orders.customer_id', 'orders.created_at')
->get();
I got this query, it fetch results from my database, based on relationships.
The query works fine, but it grabs the first entry from the database/table and not the first value of the array.
How can I fix that?
$motor = Motor::query()
->where([
['effect_id', '=', $request->effect_id],
['poles', '=', $request->poles],
['voltage_id', '=', $request->voltage_id],
['active', '=', 1],
])
->whereHas('MotorSize', function (Builder $query) {
$query->whereIn('mounting', ['B5', 'B14', 'B34', 'B35']);
})
->firstOrFail();
I have tried different things, such as:
Adding the orderBy to the Motor model and created a "priority" field in my database, giving each a number between 1 and 100:
(i actually thought this would work, but it still grabs the first entry from the table)
public function MotorSize()
{
return $this->belongsTo('App\MotorSize')->orderBy('priority', 'ASC');
}
I also tried something like this, but it's a mess and never got it to work:
$query->where(function ($query) {
$query->where('mounting', 'like', 'B5');
})
->orWhere(function($query) {
$query->where('mounting', 'like', 'B14');
})
->orWhere(function($query) {
$query->where('mounting', 'like', 'B34');
})
->orWhere(function($query) {
$query->where('mounting', 'like', 'B35');
});
Any suggestions will be welcome :)
I have an episodes table and an episode_Listen table, which is a One episode to Many listens
I want to get the 6 episodes with highest listens. I've tried every single solution like the following:
$trending = Episode::where('active', true)
->get()->sortBy(function($podcast) {
return $podcast->latestListens;
});
Or
$trending = Episode::where('active', true)
->withCount('listens')
->orderBy('listens_count', 'desc')
->get();
Or
$trending = Episode::join('episode_listens', function ($join) {
$join->on('episode_listens.episode_id', '=', 'episodes.id');
})
->groupBy('episodes.id')
->orderBy('count', 'desc')
->select((['episodes.*', DB::raw('COUNT(episode_listens.podcast_id) as count')]))->paginate(6);
But the execution time always exceeds 6 seconds, because I've around 500k listens records in the database, and they'll go millions in a very short period of time.
Any thoughts?
Thanks in advance
I have an 'implementation' table that contains relationships to retrieve projects and scores.
The scores table contains a" user_id "field.
I would like to collect all the implementations but with only the score which contains the user_id.
My original query.
public function getImplementations($id, $student)
{
$data = Implementation::where('event_id', $id)->where('student_id', $student)->with('project', 'score')->get();
return response()->json($data);
}
My test for get only the score from specific user (only one score per user per implementation, so no conflict possible)
$data = Implementation::where('event_id', $id)
->where('student_id', $student)->with('project', 'score')
->whereHas('score', function ($query) {
$query->where('user_id', Auth::user()->id);
})->get();
But that does not give the expected result. This is not the right method and I do not know the right one.
Thanks for your help
I am not sure if there's a need to eager-load and constrain a relationship simultaneously. Does the following provide you with the expected result?
$data = Implementation::where('event_id', $id)
->with([
'project',
'score' => function ($query) {
$query->where('user_id', Auth::id());
}
])
->where('student_id', $student)
->get();
I have two tables, the typical master-detail, what I intend to do is obtain the master's records, while the registration number obtained by means of a where of the relationship is greater than n
I've been doing this until now
Master::withTrashed()
->with('details')
->withCount(['details' => function ($query) {
$query->whereDate('date_init', '<', Carbon::now()->toDateString());
}]);
with this I get the master and its details with the given conditions, but there are teachers that the count of the relationship is 0, that I want to ignore. How can I do this?
What you are looking for is the following query:
Master::withTrashed()
->with(['details' => function ($query) {
$query->whereDate('date_init', '<', now());
}])
->whereHas('details', function ($query) {
$query->whereDate('date_init', '<', now());
})
->get();
The query literally means:
Give me all Masters, also the deleted ones, which have at least one attached Detail with an initialization date in the past. Also eager load all attached Details which have been initialized in the past.
Master::withTrashed()
->has('details')
->with('details')
->withCount(['details' => function ($query) {
$query->whereDate('date_init', '<', Carbon::now()->toDateString());
}]);
Fixed whereHas to has, as pointed out by Namoshek.