当涉及不同年份时,为什么按日期范围查询不起作用?



我在Laravel中查询日期范围,这使我头脑清醒。最初的查询工作没有错误,但我已经检测到,如果日期范围是不同的年份之间(12-2020至01-2021),它不返回任何记录。我有点厌倦了检查代码,但我没发现问题。

我在这里放置了将数据保存在数组中的查询,以及稍后在返回值之前应用日期过滤器的检查。

public function getData($filters) {
$tasks = $this->getModel()
->whereIn('tasks.department_id', $filters['departmentIds'])
->join('departments', 'departments.id', '=', 'tasks.department_id')
->join('deliverables as dev', 'dev.id', '=', 'tasks.deliverable_id')
->leftJoin('deliverables as sub', 'sub.id', '=', 'tasks.subdeliverable_id')
->leftJoin('workers as st_workers', 'st_workers.id', '=', 'tasks.start_worker_id')
->leftJoin('workers as end_workers', 'end_workers.id', '=', 'tasks.end_worker_id')
->leftJoin('type_task_statuses', 'type_task_statuses.id', '=', 'tasks.status_id')
->leftJoin('incidences', 'incidences.task_id', '=', 'tasks.id')
->select('tasks.id', 'departments.name as department', 'tasks.start_worker_id', 'tasks.end_worker_id', 'st_workers.short_name as start_worker',
'end_workers.short_name as end_worker', 'tasks.plane', 'tasks.st', 'dev.name as deliverable', 'sub.name as subdeliverable',
'tasks.quantity', 'tasks.other_deliverable', 'tasks.start_prevision_date', 'tasks.end_prevision_date', 'tasks.start_date',
'tasks.end_date', 'tasks.prevision_hour', 'tasks.incurred_hour', 'type_task_statuses.display_name as status', 'type_task_statuses.color', 'tasks.advance', 'tasks.agreed',
'tasks.disagreed_date', 'tasks.supervised', DB::raw('COUNT(incidences.id) as count_incidences'))
->groupBy('tasks.id');
if (array_key_exists('fromDate', $filters) && $filters['fromDate']) {
$tasks->whereRaw('(DATE_FORMAT(tasks.end_date, "%m-%Y") >= "'.$filters['fromDate'].'" OR tasks.end_date is NULL)');
}
if (array_key_exists('toDate', $filters) && $filters['toDate']) {
$tasks->whereRaw('(DATE_FORMAT(tasks.end_date, "%m-%Y") <= "'.$filters['toDate'].'" OR tasks.end_date is NULL)');
}
return $tasks;
}

我建议将您的输入格式化为应用程序中的日期范围,而不是在数据库端应用格式化,请参阅我对anti -patterns的另一个答案

假设您有以下输入来匹配数据库

中的日期
$filters['fromDate'] ='12-2020';
$filters['toDate'] = '01-2021';

相当于实际

中的日期范围

From 2020-12-01 00:00:00 To 2021-01-31 23:59:59


让我们试着把过滤器的输入转换成这个范围格式

/** 2020-12-01 00:00:00 */
$fromDate = CarbonCarbon::createFromFormat('d-m-Y', '01-'.$filters['fromDate'])->startOfMonth()->format('Y-m-d H:i:s');
/** 2021-01-31 23:59:59 */
$toDate = CarbonCarbon::createFromFormat('d-m-Y', '01-'.$filters['toDate'])->endOfMonth()->format('Y-m-d H:i:s');

现在你可以很容易地在你的查询和数据库端应用这些范围,你不需要任何类型的格式化

if (array_key_exists('fromDate', $filters) && $filters['fromDate']) {
$fromDate = CarbonCarbon::createFromFormat('d-m-Y', '01-' . $filters['fromDate'])->startOfMonth()->format('Y-m-d H:i:s');
$tasks->where(function ($query) use ($fromDate) {
$query->whereNull('tasks.end_date')
->orWhere('tasks.end_date', '>=', $fromDate);
});
}
if (array_key_exists('toDate', $filters) && $filters['toDate']) {
$toDate = CarbonCarbon::createFromFormat('d-m-Y', '01-' . $filters['toDate'])->endOfMonth()->format('Y-m-d H:i:s');
$tasks->where(function ($query) use ($toDate) {
$query->whereNull('tasks.end_date')
->orWhere('tasks.end_date', '<=', $toDate);
});
}

最新更新