Kar*_*hik 1 php laravel laravel-5.5 laravel-5.8
我需要获取 Laravel 中未来 7 天内过生日的客户列表。我使用以下查询。该查询还显示已过的生日。
$customerslist=Customers::WhereRaw('DAYOFYEAR(curdate()) <= DAYOFYEAR(date_of_birth) AND DAYOFYEAR(curdate()) + 7 >= dayofyear(date_of_birth)' )->OrderBy(DB::raw("DAYOFYEAR(date_of_birth)"),'ASC')->get();
Run Code Online (Sandbox Code Playgroud)
失踪的顾客
我发现使用 DAYOFYEAR 方法进行原始查询非常优雅,因为它消除了不同出生年份的所有问题。然而,它不能很好地处理闰年。
我发现 BETWEEN 和 DATE_FORMAT 的组合会产生正确的结果。它确实需要进行检查来处理岁月边缘的情况。
以下是如何在模型范围内实现此示例的示例:
public function scopeBirthDayBetween ($query, Carbon $from, Carbon $till)
{
$fromMonthDay = $from->format('m-d');
$tillMonthDay = $till->format('m-d');
if ($fromMonthDay <= $tillMonthDay) {
//normal search within the one year
$query->whereRaw("DATE_FORMAT(birthdate, '%m-%d') BETWEEN '{$fromMonthDay}' AND '{$tillMonthDay}'");
} else {
//we are overlapping a year, search at end and beginning of year
$query->where(function ($query) use ($fromMonthDay, $tillMonthDay) {
$query->whereRaw("DATE_FORMAT(birthdate, '%m-%d') BETWEEN '{$fromMonthDay}' AND '12-31'")
->orWhereRaw("DATE_FORMAT(birthdate, '%m-%d') BETWEEN '01-01' AND '{$tillMonthDay}'");
});
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
$users = User::birthDayBetween(Carbon::now(), Carbon::now()->addWeek())->get()
Run Code Online (Sandbox Code Playgroud)
要添加生日而不是出生日期的排序,更多原始查询和 DATE_FORMAT 可以提供帮助。
$users = User::query()
->birthDayBetween($from, $till)
->orderByRaw("DATE_FORMAT(birth_date,'%m%d')")
->orderByRaw("DATE_FORMAT(birth_date,'%y') desc")
->orderBy('first_name')
->get();
Run Code Online (Sandbox Code Playgroud)
注意:查看年份边缘时,排序将会关闭,因为生日在明年年初的用户将首先排序。我选择在前端解决这个问题。