Say, I have a table in the database (SQL Server 2008) with data similar to this (but much, much bigger):
| ID | SCORE | GROUP |
-----------------------
| 10 | 1 | A |
| 6 | 2 | A |
| 3 | 3 | A |
|----|-------|-------|
| 8 | 5 | B |
|----|-------|-------|
| 4 | 1 | C |
| 9 | 3 | C |
| 2 | 4 | C |
| 7 | 4 | C |
|----|-------|-------|
| 12 | 3 | D |
| 1 | 3 | D |
| 11 | 4 | D |
| 5 | 6 | D |
I'd like to get the ID
of the top and bottom records for each GROUP
, where the records for each group are ordered by SCORE
(and supplementarily, ID
), like this:
| GROUP | MIN_ID | MAX_ID |
----------------------------
| A | 10 | 3 |
| B | 8 | 8 |
| C | 4 | 7 |
| D | 1 | 5 |
The question is: how can I achieve this?
So far, I have been attempting solutions based on the RANK()
function, but haven't managed find a query which both produces the correct output and is vaguely efficient or maintainable.
Notes:
The example is simplified. My 'table' is actually the output of an already complex query, which I'm looking to add the final stages to. I would prefer to only select from the table once.
If possible, it would be good to have a general solution which would allow me to select the top and bottom n
values per group.
The ID
s are not in convenient order.