从复杂的原始 SQL-query 创建 Eloquent 模型
Create Eloquent model from complex raw SQL-query
我正在考虑该方法的正确设计,该方法为用户提供了很久以前最后一次约会的客户列表。
所以我有 2 table(简体):
- 客户(id,first_name)
- 约会(id,client_id,日期时间)
我想做的是:获取很久以前的最后一次约会的 3 位客户的列表。
所以我做了什么:我 select 有最早约会的用户和 return 他们(使用复杂的 SQL 查询)。然后我从中创建模型。
这个案例的设计好吗?
use Illuminate\Database\Eloquent\Collection;
class ClientRepository {
/**
* Get clients with no appointments in the near history (sort by the date of last appointment ASC)
*
* @todo Make a better way to find falling clients (more Laravelish maybe?)
* @param $count How many clients should method return
* @return Illuminate\Database\Eloquent\Collection
*/
static public function getLost($count=3) {
//this SQL looks too long but works as charm
//solution based on
$sql = "
SELECT * FROM (
SELECT clients.*, clients.id AS cli_id , appointments.datetime AS last_appointment_datetime
FROM clients
INNER JOIN appointments ON clients.id=appointments.client_id
ORDER BY appointments.datetime ASC
) AS tmp_table
GROUP BY cli_id
ORDER BY last_appointment_datetime ASC
LIMIT ?
";
$users = \DB::select($sql,[$count]);
foreach($users as $key=>$user) {
$user_array = (array)$user;
$users[$key] = new Client();
$users[$key]->forceFill($user_array);
}
$collection = new Collection($users);
return $collection;
}
}
您可以无需子选择并使用Eloquent的查询构建器:
//select clients joined with their appointments
$users = Client::join('appointments', 'appointments.client_id', '=', 'clients.id')
//group rows by client ID (if client has multiple appointments then client would appear multiple times in the result set
->groupBy('clients.id')
//sort them by date of last appointment in descending order
->orderByRaw('MAX(appointments.datetime)')
->get();
我正在考虑该方法的正确设计,该方法为用户提供了很久以前最后一次约会的客户列表。
所以我有 2 table(简体):
- 客户(id,first_name)
- 约会(id,client_id,日期时间)
我想做的是:获取很久以前的最后一次约会的 3 位客户的列表。
所以我做了什么:我 select 有最早约会的用户和 return 他们(使用复杂的 SQL 查询)。然后我从中创建模型。
这个案例的设计好吗?
use Illuminate\Database\Eloquent\Collection;
class ClientRepository {
/**
* Get clients with no appointments in the near history (sort by the date of last appointment ASC)
*
* @todo Make a better way to find falling clients (more Laravelish maybe?)
* @param $count How many clients should method return
* @return Illuminate\Database\Eloquent\Collection
*/
static public function getLost($count=3) {
//this SQL looks too long but works as charm
//solution based on
$sql = "
SELECT * FROM (
SELECT clients.*, clients.id AS cli_id , appointments.datetime AS last_appointment_datetime
FROM clients
INNER JOIN appointments ON clients.id=appointments.client_id
ORDER BY appointments.datetime ASC
) AS tmp_table
GROUP BY cli_id
ORDER BY last_appointment_datetime ASC
LIMIT ?
";
$users = \DB::select($sql,[$count]);
foreach($users as $key=>$user) {
$user_array = (array)$user;
$users[$key] = new Client();
$users[$key]->forceFill($user_array);
}
$collection = new Collection($users);
return $collection;
}
}
您可以无需子选择并使用Eloquent的查询构建器:
//select clients joined with their appointments
$users = Client::join('appointments', 'appointments.client_id', '=', 'clients.id')
//group rows by client ID (if client has multiple appointments then client would appear multiple times in the result set
->groupBy('clients.id')
//sort them by date of last appointment in descending order
->orderByRaw('MAX(appointments.datetime)')
->get();