row_number / dense_rank (Groupe et île)

Vous findez ci-dessous datatables de test à utiliser. Ce dont j'ai besoin, c'est d'une fonction dense_rank, rank, row_number pour get les lignes numérotées comme dans "NoRequired". J'ai testé toutes les fonctions rank et row_number et j'ai même essayé d'utiliser les instructions WITH, mais je n'ai pas encore trouvé de solution.

Je suppose que le problème principal ici est que la "fonction de rang" doit sauter une séquence une fois qu'il y a une valeur de key différente entre …

DECLARE @data TABLE (ID int IDENTITY(1,1), X int, NoRequired int); INSERT INTO @data(X, NoRequired) VALUES (1000,1), (1000,1), (800,2), (600,3), (1000,4), (1000,4), (800,5); SELECT * FROM @data; 

C'est un problème de "groupe et îles". Une méthode simple consiste à utiliser lag et une sum cumulée:

 select d.*, sum(case when prev_x = x then 0 else 1 end) over (order by id) as NoRequired from (select d.*, lag(x) over (order by id) as prev_x from @data d ) d; 

L'idée est d'identifier les lignes où la valeur change, puis de faire une sum cumulative de ces valeurs.

 DECLARE @data TABLE (ID int IDENTITY(1,1), X int, NoRequired int); INSERT INTO @data(X, NoRequired) VALUES (1000,1), (1000,1), (800,2), (600,3), (1000,4), (1000,4), (800,5); SELECT D.ID, DX, D.NoRequired, MAX(RQ.RN) MyVal FROM @DATA D JOIN (SELECT D1.ID, ROW_NUMBER() OVER (ORDER BY D1.ID) RN FROM @data D1 LEFT JOIN @data D2 ON D1.ID = D2.Id + 1 AND D1.X = D2.X WHERE D2.Id IS NULL) RQ ON RQ.ID <= D.ID GROUP BY D.ID, DX, D.NoRequired ORDER BY D.ID