I have temporary table (@TempPackages) which looks like this:
EntryId (PK) PackageId SubProductID SubProductSequence
1 1111 17 3
2 1111 28 4
3 1111 33 1
4 1111 67 5
5 1111 122 2
6 2222 18 4
7 2222 29 5
8 2222 33 9
9 2222 103 7
10 2222 99 11
11 3333 256 5
12 3333 333 6
13 3333 789 3
14 3333 1023 2
15 3333 9845 1
I need a query which will give me the rows with the minimum/maximum SubProductSequence value for each unique PackageId. For the table above, the query would return this:
EntryId (PK) PackageId SubProductID SubProductSequence
3 1111 33 1
4 1111 67 5
6 2222 18 4
10 2222 99 11
12 3333 333 6
15 3333 9845 1
The EntryId column was something that I added while trying to solve this, as it gives me a unique column to join the same table on to (to ensure I still only end up with 15 rows in my joined table).
I tried this – just to get the MIN():
SELECT
*
FROM
@TempPackages p1
INNER JOIN
@TempPackages p2 ON p1.EntryId = p2.EntryId
AND p1.SubProductSequence = (
SELECT
MIN(SubProductSequence)
FROM
@DeparturesToUpdate)
Obviously this is wrong, because the INNER JOIN is superfluous and the SELECT MIN() clause is wrong as it selects the rows with the minimum overall sequence numbers, not the minimum sequence numbers per package.
Any suggestions about the best way to do this?
One way is to use the
ROW_NUMBER()function:ROW_NUMBER()is a ranking function that is used withOVERclause. What it basically does in this case, is it groups the rows with samePackageId(that is done with thePARTITION BY PackageId), then orders them bySubProductSequence(ascending or descending) and assigns a row_number, starting from 1 for each packageId.So, the subquery would return this, if it was run alone:
The
WHEREcondition added in the external query is obvious afterwards.