2017-11-24 13 views
3

두 datetimes 사이의 차이를 계산하려고합니다. tasks 많은 task_interactions을 가지고 있으며, task_interactionstasks에 속하는 :Laravel Carbon - 데이터베이스 항목 간의 시간 계산

나는 두 가지 모델, taskstask_interactions는, 그들은 다음과 같이 관련되어 있습니다.

사용자는 작업 상태를 "진행 중", "일시 중지"및 완료 중 하나로 변경할 수 있습니다. 사용자는 '진행 중'과 '일시 중지'사이에서 상태를 여러 번 변경하지만 작업이 완료되면 더 이상 작업 상태를 변경할 수 없습니다.

모든 상호 작용은 을 user_id로, created_at을 datetime으로 사용하여 task_interactions 테이블에 저장됩니다. 표에는 id ; task_id ; status ; comments ; created_by ; created_at 열이 있습니다.

여기 = 작업 ID에 대한 exemple 노나의 1 : 내가 총 시간은 하나 개의 작업에 소비해야하는

# id, task_id, status, comments, created_by, created_at 
144, 1, In Progress, , 1, 2017-11-14 09:42:20 
145, 1, Paused, , 1, 2017-11-14 09:45:53 
146, 1, In Progress, , 1, 2017-11-14 09:46:57 
147, 1, Paused, , 1, 2017-11-14 09:49:57 
148, 1, In Progress, , 1, 2017-11-14 10:00:10 
149, 1, Paused, , 1, 2017-11-14 10:06:25 
150, 1, In Progress, , 1, 2017-11-14 10:07:26 
151, 1, Paused, , 1, 2017-11-14 10:08:11 
153, 1, Paused, , 1, 2017-11-14 11:27:04 
154, 1, In Progress, , 1, 2017-11-14 11:27:21 
155, 1, Paused, , 1, 2017-11-14 11:57:38 

것은,이다, 나는 In ProgressPaused 사이의 시간을 결정해야합니다. PausedIn Progress 사이의 시간은 적합하지 않습니다.

나는 이걸로 strugling 오전. 나를 도울 수있는 사람이 있습니까?

미리 감사드립니다.

내 질문에 약간의 멍청한 소리가 들리면, 경험이 많지 않습니다. 나는 task_id = X가있는 모든 task_interactions를 통해 @foreach 루프를 수행해야한다고 생각합니다. 내가 지금까지

@foreach ($tasks as $task) 
    @foreach ($task->interactions as $interactions) 
{{ In here, every time my loop returns a status = "In progress" i should mark that time, and if that the next loop returns a "Paused", i should count the difference between these two. And sum all other equal cases in the loop. }} 
    @endforeach 
@endforeach 

내가 정말 수행하는 방법에 대한 아무 생각이 무엇을 알고,

public function mytasks() 
    { 
     $users = User::all(); 
     $mytasks = Task::where('assigned_to','=', Auth::id())->where('status','!=','Finished')->get(); 
     $mytaskscount = Task::where('assigned_to','=', Auth::id())->count(); 
     $tasksinprogress = Task::where('status','=','In Progress')->where('assigned_to','=', Auth::id())->get(); 
     $tasksinprogresscount = Task::where('status','=','In Progress')->where('assigned_to','=', Auth::id())->count(); 
     $taskspaused = Task::where('status','=','Paused')->where('assigned_to','=', Auth::id())->get(); 
     $taskspausedcount = Task::where('status','=','Paused')->where('assigned_to','=', Auth::id())->count(); 
     $tasksfinished = Task::where('status','=','Finished')->where('assigned_to','=', Auth::id())->get(); 
     $tasksfinishedcount = Task::where('status','=','Finished')->where('assigned_to','=', Auth::id())->count(); 
     $tasktypes = Tasktype::all(); 
     $chapters = Chapter::all(); 

     return view('pages.tasks_my', compact('mytasks','tasktypes','chapters','tasksinprogress','taskspaused','tasksfinished','mytaskscount','tasksinprogresscount','taskspausedcount','tasksfinishedcount')); 
    } 

그리고 한 가지 더 :

요청으로

, 여기 내가보기를 통과하고 데이터의 그

+0

컨트롤러를 밀 수 있습니까? –

+0

나는이 질문에 대한 답변을 알고 싶습니다. – lewis4u

+0

이 문제를 처리 할 수있는 db 쿼리를 개인적으로 담당합니까? PHP로 결과를 반복하는 것은 마음에 오는 것입니다. – Chay22

답변

1

이것은 엄격한 MySQL이지만 트릭을해야합니다. 원시 sql 명령어를 사용하여 laravel에서 직접 호출하거나 Laravel 코드로 다시 작성해야합니다.

select SEC_TO_TIME(
    sum( 
     timediff(
      if(task_end.created_at is null, 
       NOW(), 
       task_end.created_at), 
      task_start.created_at))) 
from task_interactions task_start 
left join task_interactions task_end 
    ON task_end.task_id = task_start.task_id 
    AND task_end.status IN ('Pause', 'Finished') 
    AND task_end.created_at = (
     SELECT min(created_at) 
     FROM task_interactions 
     WHERE status = task_end.status 
     AND created_at >= task_start.created_at 
    ) 
WHERE task_start.task_id = 1 
AND task_start.status = 'In Progress' 
+0

이것이 내가 Laravel을 좋아하는 주된 이유입니다 ... PHP와 SQL의 바닐라 코드는 너무 추하고 읽기가 어렵습니다 ... Laravel Eloquent에게 약간의 시간을 할애 해 줄 수 있다면 좋을 것입니다. – lewis4u

+0

뭐가 그렇게 되나요? 그때 읽기 어려워? 이것은 기본 SQL입니다 ... 모든 작업 _ 작업을 '진행 중'상태로 유지하십시오. 나는 그것들을 task_start라고 불렀다; 그때 나는 같은 task_id (와 나는 그 별칭 task_end)로 다른 작업들에 왼쪽 join을한다; 해당 참여의 경우 일시 중지되었거나 완료된 작업 만 필요합니다. 또한 - 결국 그 첫 번째 과제를 원합니다 ... Laravel은 좋지만, Eloquent를 사용하여 이것을 원한다면 여전히 복잡 할 것입니다. Laravel은 훌륭한 도구이지만, 여전히 당신이하고있는 것을 알 필요가 있습니다. –

+0

코드가 너무 많아서 laravel 및 코드가 적어집니다. – lewis4u

0

나는 David의 대답을 권하고 싶습니다. MySQL을 사용하는 것이 편한 경우. 이 일시 중지 된 경우 작업이 &을 시작했다 처음으로 사이

계산의 차이 :

$start = Carbon::parse($startTask->created_at); 
$pause = Carbon::parse($endTask->created_at); 

$diffInSeconds = $pause->diffInSeconds($start) 

이 당신에게 초 총 차이를 제공해야합니다 같은 작업 때에이 같은 그것을 할 수있다 시작한 후 & 일시 중지되었습니다. 이제 작업이 다시 시작된 후 & 일시 중지 된 경우에이 방법을 반복해야합니다.

+0

이것은 좀 이상하게 들릴지 모르지만, 당신의 접근법을 이해하지만 foreach 루프 안에 넣는 방법에 대해서는 잘 모른다. 나는 경험이 많지 않다. 내가하는 일은 내가 컨트롤러에서 필요로하는 데이터를 걸러 낸 다음 내 정보를 처리하는 것이다. 나는 그것의 틀린 것을 안다 –

+0

당신이 배열로 업무를위한 모든 중지하고 시작하는 입장을 얻는 것을 필요로하기 때문에 확실히 그것의 쉬운. 그런 다음 작업에 대한 시작 항목을 구문 분석하기 만하면됩니다. –

+0

한번 시도해 보겠습니다. 고마워. –