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

kandroid's avatar

Group all matches by create_at field with a count

Hi all,

I wonder if you could advise me on how to do the following.

I have a DB table that stores a ton of pings/heartbeats from remote devices. Each record simply has id, device_id and created_at columns.

What I am attempting to do is get all by device_id and group by the created_at date (not time) with a count for each on that day.

The output should look like:

Array ( [0] => stdClass Object ( [created_at] => 2020-07-23 11:51:00 [count] => 32 )

[1] => stdClass Object
    (
        [created_at] => 2020-07-24 00:01:43
        [count] => 52
    )

[2] => stdClass Object
    (
        [created_at] => 2020-07-25 00:01:43
        [count] => 48
    )

[3] => stdClass Object
    (
        [created_at] => 2020-07-26 00:01:41
        [count] => 48
    )

[4] => stdClass Object
    (
        [created_at] => 2020-07-27 00:01:42
        [count] => 3
    )

)

I have following but it does not give me what I need:

        $results = DB::table('deviceactions')
                ->select(DB::raw('created_at, count(created_at) as count'))
                ->where('device_id', $device->id)
                ->where('created_at', '>=', $start)
                ->where('created_at', '<=', $end)
                ->groupBy('created_at')
                ->get()->toArray();

Instead I get an instance for each record, with a count of 1, even if on the same day but different time.

Array ( ...

[26] => stdClass Object
    (
        [created_at] => 2020-07-21 21:38:45
        [count] => 1
    )

[27] => stdClass Object
    (
        [created_at] => 2020-07-21 22:08:45
        [count] => 1
    )

[28] => stdClass Object
    (
        [created_at] => 2020-07-21 22:38:45
        [count] => 1
    )

[29] => stdClass Object
    (
        [created_at] => 2020-07-21 23:08:45
        [count] => 1
    )

[30] => stdClass Object
    (
        [created_at] => 2020-07-21 23:38:45
        [count] => 1
    )

[31] => stdClass Object
    (
        [created_at] => 2020-07-22 00:02:07
        [count] => 1
    )

[32] => stdClass Object
    (
        [created_at] => 2020-07-22 00:32:07
        [count] => 1
    )

[33] => stdClass Object
    (
        [created_at] => 2020-07-22 01:02:07
        [count] => 1
    )

)

Is this possible or should I simply get results and loop through and create the output I need?

Thanks for any advice...

0 likes
3 replies
MarianoMoreyra's avatar
Level 25

Hi @kandroid

You should get the DATE only from the created_at field so you can group on it:

$results = DB::table('deviceactions')
    ->select(DB::raw('DATE(created_at) as created_date, count(created_at) as count'))
    ->where('device_id', $device->id)
    ->whereBetween('created_at', [$start, $end])
    ->groupBy('created_date')  // note that I'm grouping using the alias for the DATE
    ->get()->toArray();

Note also that I've replaced your 2 where clauses for filtering the date, with a whereBetween to have more readability.

Hope this works for you!

Please or to participate in this conversation.