How can I get SQL Server to return the first value (any one, I don't care, it just needs to be fast) it comes across when aggregating?
For example, let's say I have:
ID Group
1 A
2 A
3 A
4 B
5 B
and I need to get any one of the ID's for each group. I can do this as follows:
Select
max(id)
,group
from Table
group by group
which returns
ID Group
3 A
5 B
That does the job, but it seems stupid to me to ask SQL Server to calculate the highest ID when all it really needs to do is to pick the first ID it comes across.
Thanks
PS - the fields are indexed, so maybe it doesn't really make a difference?
There is an undocumented aggregate called
ANY
which is not valid syntax but is possible to get to appear in your execution plans. This does not provide any performance advantage however.Assuming the following table and index structure
I have also populated with sample data such that there are many rows per group.
Your original query
Gives
Table 'T'. Scan count 1, logical reads 1367
and the planRewritten to get the
ANY
aggregate...Gives
Table 'T'. Scan count 1, logical reads 1367
and the planEven though potentially SQL Server could stop processing the group as soon as the first value is found and skip to the next one it doesn't. It still processes all rows and the logical reads are the same.
For this particular example with many rows in the group a more efficient version would be a recursive CTE.
Which gives
The logical reads are much less as it retrieves the first row per group then seeks into the next group rather than reading a load of records that don't contribute to the final result.