あなたが望むことをする通常の方法は、density_rank関数です:
select key, val,
dense_rank() over (order by key, val)
from t
ただし、これは最後のグループを分離する問題には対処しません。
これを処理するには、「id」列があると想定する必要があります。SQLのテーブルには順序がないため、順序が必要です。SQL Server 2012を使用している場合は、lag()関数を使用して必要なものを取得できます。ラグを使用して、キーとvalのペアが連続する行で同じであるかどうかを確認します。
with t1 as (
select id, key, val,
(case when key = lead(key, 1) over (order by id) and
val = lead(val, 1) over (order by id)
then 1
else 0
end) as SameAsNext
from t
)
select id, key, val,
sum(SameAsNext) over (order by id) as GroupNum
from t
SQL Server 2012(累積合計がある)がない場合は、自己結合を実行して各グループの先頭を識別する必要があります。
select t.*,
from t left outer join
t tprev
on t.id = t2.id + 1 and t.key = t2.key and t.val = t2.val
where t2.id is null
これで、結合を使用してグループを最小IDとして割り当てます。
select t.id, t.key, t.val,
min(tgrp.id) as GroupId
from t left outer join
(select t.*,
from t left outer join
t tprev
on t.id = t2.id + 1 and t.key = t2.key and t.val = t2.val
where t2.id is null
) tgrp
on t.id >= tgrp.id
これらを連続した数値にする場合は、サブクエリに入れて、dense_rank()を使用します。