Any answer that joins a table on it self will create a square law...
- a JOIN b ON a.class = b.class AND a.age >= b.age
- on average the >= condition will be true for half the class
- 6 people in a class
->6*6/2 = 18
- 10 people in a class
->10*10/2 = 50
-> very rapid growth
As the table sizes grow the performance will degrade rapidly. If you're keeping things small and they won't grow much, is it an issue? Your call there...
An alternative involves more code, but grows linearly...
- First, insert all the records intoa new table, with an IDENTITY field, ordered by Class then Age
- Now, for each class, find the MIN(id)
- Now, for each class, rinf the record where is = MIN(id) + 8 (for the 9th eldest)
There are a lot of ways of doing the last 2 steps. I personally would use...
SELECT
[USER_WITH_IDS].id,
[USER_WITH_IDS].class,
[USER_WITH_IDS].age
FROM
[USER_WITH_IDS]
WHERE
[USER_WITH_IDS].id = (
SELECT
MIN([min].ID) + 8
FROM
[USER_WITH_IDS] AS [min]
WHERE
[min].class = [USER_WITH_IDS].class
)
What this gives is...
- One pass to create the new IDs
- One pass to get the MIN(id) for each class
One pass to get the records you need
And depending on how good the optimiser is, using an index (class then id) would allow it to combine the last 2 passes into 1 pass.
2 or 3 passes, no matter how big the table or class size gets. Linear, not square law...