Since you are using a primary key on group_id, time
, you can use a standard exclusion join, as opposed to a GROUP BY
, since the records are unambiguous.
In this instance to obtain the group_id
and MAX(time)
with the corresponding other values you would LEFT JOIN table AS b ON a.group_id = b.group_id AND a.time < b.time
Then remove the undesired entries by filtering the left join table results with WHERE b.group_id IS NULL
Exclusion Join
DB-Fiddle
SELECT t1.group_id, t1.`time`, t1.`data`
FROM `table` AS t1
LEFT JOIN `table` AS t2
ON t2.group_id = t1.`group_id`
AND t1.`time` < t2.`time`
WHERE t1.group_id BETWEEN ...
AND t1.others = ...
AND t2.group_id IS NULL;
Result:
| group_id | time | data |
| -------- | ------------------- | ----- |
| 1 | 2020-11-30 13:00:00 | 15 |
| 2 | 2020-11-30 12:30:00 | 254 |
| 3 | 2021-02-21 18:00:00 | 25565 |
Alternatively, since you have group_id, time
as your primary key, you can use a compound IN
subquery criteria with the MAX(time)
.
Compound IN
Subquery
DB-Fiddle
SELECT t1.group_id, t1.`time`, t1.`data`
FROM `table` AS t1
WHERE t1.others = ....
AND (t1.group_id, t1.`time`) IN(
SELECT group_id, MAX(`time`)
FROM `table`
WHERE group_id BETWEEN ....
GROUP BY group_id
);
Result:
| group_id | time | data |
| -------- | ------------------- | ----- |
| 1 | 2020-11-30 13:00:00 | 15 |
| 2 | 2020-11-30 12:30:00 | 254 |
| 3 | 2021-02-21 18:00:00 | 25565 |