I want to group by one column, get both min and max of a second column, and (this is the tricky part!) get the value from a third column where the second column has its min value in the group.
Example:
MyTable:
ID TS GRP
==================
1 20 A
2 20 B
3 10 A
4 30 A
5 10 B
6 40 A
Desired result (ID should be the value from the record where TS has its minimum):
ID MIN_TS MAX_TS GRP
============================
3 10 40 A
5 10 20 B
In general, the grouping query is very easy:
SELECT <???> AS ID, MIN(TS) AS MIN_TS, MAX(TS) AS MAX_TS, GRP
FROM MyTable
GROUP BY GRP
But what about the ID part? It doesn't work this way with grouping, right? But why? And what's the best workaround?
MySQL MAX() function with GROUP BY retrieves maximum value of an expression which has undergone a grouping operation (usually based upon one column or a list of comma-separated columns).
GROUP BY Clause is utilized with the SELECT statement. GROUP BY aggregates the results on the basis of selected column: COUNT, MAX, MIN, SUM, AVG, etc. GROUP BY returns only one result per group of data. GROUP BY Clause always follows the WHERE Clause.
Absolutely. It will result in filtering the records on your date range and then grouping it by each day where there is data.
Cannot use an aggregate or a subquery in an expression used for the group by list of a GROUP BY clause. The original idea was to create the table in beginning of the query, so the (SELECT * FROM #TBL) could be used on the query itself, instead of defining the names on each GROUP BY.
Do the aggregation in a subquery, then look up the ID for each group in another subquery:
SELECT
(SELECT TOP(1) id FROM MyTable WHERE grp = agg.grp ORDER BY ts DESC) AS id,
min_ts, max_ts, grp
FROM (SELECT min(ts) AS min_ts, max(ts) AS max_ts, grp
FROM MyTable
GROUP BY grp) agg
Or use window functions:
SELECT id, min_ts, max_ts, grp
FROM (SELECT
id,
min(ts) OVER (PARTITION BY grp) min_ts,
max(ts) OVER (PARTITION BY grp) max_ts,
grp,
row_number OVER (PARTITION BY grp ORDER BY ts) rn
FROM MyTable)
WHERE rn = 1;
This query uses window functions to calculate min_ts
and max_ts
for each group, and then filters to only include the first row for each group (ordered by ts
).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With