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

Bakanyaka's avatar

Is this too complex for Eloquent?

Let's say I have 3 tables (unnecessary columns omitted in example):

  • issues table with columns: id, status_id, assigned_to_id - issues currently assigned to users
  • statuses table with columns: id, is_closed - issues statuses
  • time_entries table with columns: assignee_id, issue_id, spent_on, hours - issues that users spent time on

I need to calculate the sum of the number of open issues currently assigned to each user and the number of issues that user spent time on within given period. Also following should not be counted multiple times:

  • If multiple time entries exist for same issue
  • If user spent time on issue and issue is currently assigned to him.

That's my code atm which works fine according to my tests:

        $query = 'select assignee_id, COUNT(*) as participated_issues_count from (';
        $query .= 'select id, assigned_to_id as assignee_id from issues where exists (select * from statuses where issues.status_id = statuses.id and is_closed = ?)';
        $query .= ' UNION ';
        $query .= 'select distinct issues.id as id, time_entries.assignee_id from time_entries inner join issues on time_entries.issue_id = issues.id where spent_on > ? and spent_on < ?';
        $query .= ') s group by assignee_id';
        $participatedIssuesCount = DB::select($query, [0, $periodStartDate, $periodEndDate]);              

Same as SQL query:

select assignee_id, COUNT(*) as participated_issues_count from (select id, assigned_to_id as assignee_id from issues where exists (select * from statuses where issues.status_id = statuses.id and is_closed = ?) UNION select distinct issues.id as id, time_entries.assignee_id from time_entries inner join issues on time_entries.issue_id = issues.id where spent_on > ? and spent_on < ?) s group by assignee_id

But this is raw SQL. I spent a long time trying to do the same as Eloquent or Query Builder query but it never works as I need it to.

I tried this:

        $spentIssues =  TimeEntry::spentWithin($periodStartDate, $periodEndDate)
            ->join('issues', 'time_entries.issue_id', '=', 'issues.id')
            ->select('issues.id as id', 'time_entries.assignee_id')
            ->distinct();

        $participated_issues_count = Issue::open()
            ->select('id', 'assigned_to_id as assignee_id')
            ->union($spentIssues)
            ->groupBy('assignee_id')
            ->select(DB::raw('count(*) as participated_issues_count'));

But in ends up in totally wrong SQL query which doesn't even execute:

select * from (select count(*) as participated_issues_count from "issues" where exists (select * from "statuses" where "issues"."status_id" = "statuses"."id" and "is_closed" = ?) group by "assignee_id") union select * from (select distinct "issues"."id" as "id", "time_entries"."assignee_id" from "time_entries" inner join "issues" on "time_entries"."issue_id" = "issues"."id" where "spent_on" > ? and "spent_on" < ?)

So what do you think is the best way to do this? Leave is at as raw SQL? Do separate queries and merge the result on PHP side? Or maybe you know how to do correct Eloquent query?

Thank you for spending your time reading this long post.

0 likes
4 replies
martinbean's avatar

@Bakanyaka You seem to be trying to get two different pieces of data (number of open issues, number of issues user spent time on in a time period), so these would be two different queries.

How are you intending to fetch this data? Are you wanting counts for all users in your application?

Bakanyaka's avatar

Yes. I want counts for all users. The result should be like this:

#items: array:2 [
    0 => {#1053
      +"assignee_id": "0"
      +"participated_issues_count": "1"
    }
    1 => {#1050
      +"assignee_id": "97"
      +"participated_issues_count": "2"
    }
  ]

As I said, I managed to do this with single raw sql query but I have doubts that it is the best way to do it.

Bakanyaka's avatar

Nah. It's only 50 or so users. And it's not likely to grow. Why do you think it's gonna affect perfomance? It's only a single query now.

Please or to participate in this conversation.