4

Is it possible to use Row_Number() to number rows on something else than a simple partition done with Group By ?

This is my particular case :

Id    Type    Date
--    ----    ----
 1      16    Some Date
 2      16    Some Date   
 3      16    Some Date
 4      32    Some Date
 5      64    Some Date
 6      64    Some Date
 7     128    Some Date
 8     256    Some Date
 9     256    Some Date
10     256    Some Date

I want to partition the numbering in the following way (row numbering is sorted by date) :

Id    Type    RowNb
--    ----    -----
 6      64        1
 4      32        2
 5      64        3
 9     256        1
 3      16        2
 1      16        3
 8     256        4
 7     128        5
 2      16        6
10     256        7

ie: Every other type than 32 and 64 are numbered together. The numbering of types 32 and 64 is optional because I only need to sort the others one.

What I really want to do, is retrieve all the rows with type 32 and 64 and only the row with the lowest date from the other type. The reason why I'm asking this specific question is that in the future it is possible that I will have to retrieve more than just the first column and I think it will be easier if I can number my rows like that. If you have another solution, I'm all ears.

krtek
  • 26,334
  • 5
  • 56
  • 84

1 Answers1

7

Of course you can have complex partitioning expressions, just like you could have complex grouping expressions. Here's one possible way how you could rank rows in your example:

SELECT
  Id,
  Type,
  ROW_NUMBER() OVER (
    PARTITION BY CASE WHEN Type IN (32, 64) THEN 1 ELSE 2 END
    Order BY Date
  )
FROM atable

But you'd have to repeat that condition later when filtering rows to display. So, if I were you, I might try something like this:

WITH marked AS (
  SELECT
    *,
    TypeGroup = CASE WHEN Type IN (32, 64) THEN 1 ELSE 2 END
  FROM atable
),
ranked AS (
  SELECT
    *,
    RowNb = ROW_NUMBER() OVER (PARTITION BY TypeGroup ORDER BY Date)
  FROM
)
SELECT
  Id,
  Type,
  RowNb
FROM ranked
WHERE TypeGroup = 1 OR RowNb = 1
ORDER BY TypeGroup, RowNb
Andriy M
  • 76,112
  • 17
  • 94
  • 154
  • Thank you, the first solution works like a charm for me, and like you said the second one can also be useful in some case. – krtek Nov 08 '11 at 19:20