I have created a table in html to display first rows of each id and allow user to select specific range they want to see, but not sure how I can write it in query.
With results as 
 (
   i.*, 
   ROW_NUMBER() OVER (PARTITION BY i.ID ORDER BY I.ID DESC) AS [RN] 
   FROM HolidayList AS I
   INNER JOIN (
      SELECT ID, MIN(CreateDate) FROM HolidayList GROUP BY ID
   )
   AS j ON i.ID = j.ID AND i.CreateDate = j.CreateDate
 )
 SELECT * FROM results WHERE [RN] = 1; 
UPDATED
I have tried to inject two ROW_NUMBER(), but what I received is row 10 and row 25 and they are first rows of some specific id.
 With results as 
     (
       i.*, 
       ROW_NUMBER() OVER (PARTITION BY i.ID ORDER BY I.ID DESC) AS [RN], 
       ROW_NUMBER() OVER (ORDER BY I.ID) AS [R]
       FROM HolidayList AS I
       INNER JOIN (
          SELECT ID, MIN(CreateDate) FROM HolidayList GROUP BY ID
       )
       AS j ON i.ID = j.ID AND i.CreateDate = j.CreateDate
     )
     SELECT * FROM results WHERE [RN] = 1 AND BETWEEN [R]>10 AND [R]<25
What I am really looking for is select a specific range from all the first row for each id.
FINAL
Thank to McGlothlin, finally I solve it. What I need is a nested CTE. 
With First_CTE as 
         (
           i.*, 
           ROW_NUMBER() OVER (PARTITION BY i.ID ORDER BY I.ID DESC) AS [RN]
           FROM HolidayList AS I
           INNER JOIN (
              SELECT ID, MIN(CreateDate) FROM HolidayList GROUP BY ID
           )
           AS j ON i.ID = j.ID AND i.CreateDate = j.CreateDate
         ),
         results AS 
          (
            SELECT k.*,  
            ROW_NUMBER() OVER (ORDER BY k.ID DESC) AS [R] 
            FROM First_CTE AS k WHERE k.[RN] = 1
          )
          SELECT * FROM results WHERE [R]>10 AND [R]<25
 
    