2015-08-10 23 views
9
Create Table #Test (
    ID Int Primary Key Identity, 
    Category VarChar(100) 
    ) 

Insert into #Test 
(Category) 
Values 
('Banana'), 
('Banana'), 
('Banana'), 
('Banana'), 
('Banana'), 
('Banana'), 
('Strawberry'), 
('Strawberry'), 
('Strawberry'), 
('Banana'), 
('Banana') 

Select 
    * 
    ,ROW_NUMBER() Over (Partition by Category order by ID) as RowNum 

From #Test 

Order by ID 

Quindi questo script restituisce questo:ROW_COUNT() per ricominciare in base all'ordine

ID Category RowNum 
1 Banana  1 
2 Banana  2 
3 Banana  3 
4 Banana  4 
5 Banana  5 
6 Banana  6 
7 Strawberry 1 
8 Strawberry 2 
9 Strawberry 3 
10 Banana  7 
11 Banana  8 

Il che ha perfettamente senso, tranne lo voglio restituire questo:

ID Category RowNum 
1 Banana  1 
2 Banana  2 
3 Banana  3 
4 Banana  4 
5 Banana  5 
6 Banana  6 
7 Strawberry 1 
8 Strawberry 2 
9 Strawberry 3 
10 Banana  1 
11 Banana  2 

voglio per riavviare il conteggio quando colpisce un nuovo set di Banana. Ovviamente i miei dati non sono realmente banane, ma rendono facile la visualizzazione.

Questa ricorrenza di banane è considerata nuova, quindi vogliamo iniziare a contare da uno quando lo vediamo. Mi sto tormentando il cervello e non riesco a pensare a un buon modo per farlo. Capisco perché non funziona, ma non riesco a pensare a un modo per farlo funzionare. Qualche consiglio sul modo migliore per farlo?

risposta

5

Ci sono diversi modi per avvicinarsi a questo. Un metodo è la differenza dell'approccio row_number(). Questo metodo di identificare gruppi di categorie adiacenti che sono gli stessi:

Select t.*, 
     row_number() over (partition by grp, category order by id) as rownum 
From (select t.*, 
      (row_number() over (order by id) - 
       row_number() over (partition by category order by id) 
      ) as grp 
     from #Test t 
    ) t 
Order by ID; 

Si può anche capire i gruppi che utilizzano lag(), ma questo funzionerà in SQL Server 2005 e 2008 così come le versioni più recenti.