Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

s.spaan's avatar
Level 41

Improvement of complex Eloquent Query

I have some code which queries a database on which i don't have any control (i can't change the structure or anything). In this database there is table created for every campaign in the campaigns table. To hold the history. I need to query this history tables to get the results and monitor some employees. The following code works, but i don't like it. Do you guys have any improvements?


// Some validation before..

$date_from = Carbon::parse(request('date_from'))->startOfDay();
$date_to   = Carbon::parse(request('date_to'))->endOfDay();

$department_id = request('department_id');

$campaigns = Campaign::query()
	->where('is_active', 1)
	->select('PID', 'name', 'is_active')
	->get();

$employees = Employee::where('department_id', $department_id)
	->where('is_active', 1)
	->where('funktie', Functie::TELEMARKETEER)
	->select('PID', 'department_id', 'is_active', 'function', 'friendlyname', 'fullname', 'listname', 'lastlogin', 'name', 'firstname')
	->whereHas('workdays', function ($query) use ($date_to, $date_from) {
		return $query->where('workday_datefrom', '>=', $date_from)
			->where('workday_dateto', '<=', $date_to);
	})
	->with([
		'workdays' => function ($query) use ($date_to, $date_from) {
			return $query->where('workday_datefrom', '>=', $date_from)
				->where('workday_dateto', '<=', $date_to);
		},
		'workdays.breaks'
	])
	->get()
	->keyBy('PID');

// This is the main part i don't like... 
$history = $campaigns->keyBy('PID')->map(function ($campaign) use ($employees) {
	return DB::connection('cdra')
		->table(sprintf("C%'.06d_History", $campaign->PID)) // Looks like C000085_History for example
		->whereIn('workday_pid', $employees->pluck('workdays.*.PID')->flatten()->unique()->toArray())
		->whereIn('employee_pid', $employees->pluck('PID')->toArray())
		->get();
})->flatten();

$employees = $employees->map(function ($employee) use ($history) {
	$employee->history = $history->where('employee_pid', $employee->PID)->toArray();
	
	return $employee;
});			


// Do something with this data after.. 

I don't really want to create models for each of the campaign_history tables because campaigns could be added and i don't want to change the code if that happens..

If there's any way to query all the history tables at once, or make one model to use for al it would be great.. Any suggestions are welcome!

0 likes
2 replies
judev's avatar

Hello @s.spaan you can use join query for that you have need to add a function in your models like this : public function campaign(){ return hasMany(App\Employe::class); }

And you repeat this for some Models you need to join on your query.

After that you can user join query for have a best improvement of eloquent query.

Hope this help.

s.spaan's avatar
Level 41

Hi @judev,

Thanks for the reply, but i don't understand it completly.

The Employee doesn't have a direct relation to the campaigns. So how can i create a join query with the History tables? Or do i need to create a model for each of the History tables ?

Please or to participate in this conversation.