It is not clear what you want from your question. Are you sure you want the GROUP BY indicator? If not, itโs pretty simple, and you already have many answers. But if you want GROUP BY, then this is more complicated, and no one got it right. I also assume that you only need one line per indicator, and if there are duplicate lines having the same max / min, then itโs better to just select one of them arbitrarily and not return both.
Here is my attempt using CTE (requires SQL Server 2005 or later):
WITH RowNumbers AS ( SELECT ROW_NUMBER() OVER (ORDER BY indicatorid, value) AS RowNumber, * FROM [AnalystEstimates].[dbo].[AnalystEstimateValues]), MinRowNumbers AS ( SELECT indicatorid, MIN(RowNumber) AS RowNumber FROM RowNumbers GROUP BY indicatorid), MaxRowNumbers AS ( SELECT indicatorid, MAX(RowNumber) AS RowNumber FROM RowNumbers GROUP BY indicatorid) SELECT MinRowNumbers.indicatorid, RN1.Value AS MinValue, RN1.ID AS MinValueId, RN2.Value AS MaxValue, RN2.ID AS MaxValueId FROM MinRowNumbers JOIN MaxRowNumbers ON MinRowNumbers.indicatorid = MaxRowNumbers.indicatorid JOIN RowNumbers RN1 ON MinRowNumbers.RowNumber = RN1.RowNumber JOIN RowNumbers RN2 ON MaxRowNumbers.RowNumber = RN2.RowNumber
Here are some of the data I used for testing:
CREATE TABLE AnalystEstimateValues (ID int, indicatorid int, Value int); INSERT INTO AnalystEstimateValues (ID, indicatorid , Value) VALUES (1, 1, 4), (2, 1, 4), (3, 2, 6), (4, 1, 2), (5, 2, 2), (6, 2, 5), (7, 3, 0);
And here is the result that I get:
indicatorid MinValue MinValueId MaxValue MaxValueId 1 2 4 4 2 2 2 5 6 3 3 0 7 0 7
If this is not what you want, can you try to improve your question to tell us what you want?
Update: here's an alternative solution based on Craig Young that answers, but uses joins instead of subqueries:
WITH UniqueIds AS ( SELECT IndicatorId, Value, MIN(id) AS Id FROM AnalystEstimateValues GROUP BY IndicatorId, Value) SELECT lims.IndicatorId, MinValue, T1.Id AS MinValueId, MaxValue, T2.Id AS MaxValueId FROM ( SELECT IndicatorId, MIN(Value) as MinValue, MAX(Value) as MaxValue FROM AnalystEstimateValues GROUP BY IndicatorId) lims JOIN UniqueIds T1 ON lims.IndicatorId = T1.IndicatorId AND lims.MinValue = T1.Value JOIN UniqueIds T2 ON lims.IndicatorId = T2.IndicatorId AND lims.MaxValue = T2.Value
It is cleaner and probably faster than my first version, although I did not run performance tests to verify this.