try this for reference
$reports = Report::select('zone', 'report_name')
->selectRaw('COUNT(*) as count')
->groupBy('zone', 'report_name')
->havingRaw('COUNT(*) = 1')
->orWhere(function ($query) {
$query->selectRaw('COUNT(*)')
->from('reports as sub')
->whereRaw('reports.zone = sub.zone')
->whereRaw('reports.report_name = sub.report_name')
->whereRaw('TIMESTAMPDIFF(MINUTE, reports.created_at, sub.created_at) <= 30')
->whereRaw('TIMESTAMPDIFF(MINUTE, reports.created_at, sub.created_at) >= -30');
})
->get();
the table row
| zone | report_name | created_at |
|------|-------------|----------------------|
| A | Report1 | 2023-10-19 10:00:00 |
| A | Report1 | 2023-10-19 10:15:00 |
| B | Report2 | 2023-10-19 11:00:00 |
| B | Report2 | 2023-10-19 11:45:00 |
| C | Report1 | 2023-10-19 12:00:00 |
result
| zone | report_name | count |
|------|-------------|-------|
| A | Report1 | 2 |
| B | Report2 | 2 |
| C | Report1 | 1 |
updated :
but this code still count if the created at is like this with same zone and report name
| zone | report_name | created_at |
|------|-------------|----------------------|
| A | Report1 | 2023-10-19 10:00:00 |
| A | Report1 | 2023-10-19 10:15:00 |
| A | Report2 | 2023-10-19 11:30:00 |
| A | Report2 | 2023-10-19 11:45:00 |
result is
| zone | report_name | count |
|------|-------------|-------|
| A | Report1 | 4 |
because each row is in interval 30 minutes.
so to make this will exacly 30 minute, you must provided the minutes from what minutes and day to be compared with created_at.
e.g you want report from date 2023-10-19 and time 11:30:00. so do the query to compare all the report based on date 2023-10-19 and time interval from 11:30 to 12:00 (30 minutes after 11:30)