Я играл с отчетами, и оказалось, что row_number не работает в рекурсии.
!! Я упростил пример!!
Из таблицы с 3 записями:
declare @sometable table (id int, id2 int)
insert into @sometable
select 1 as id, 11 as id2
union all
select 2, 22
union all
select 3, 33
В CTE выберите All и отметьте первую запись, которая будет исключена на следующей итерации:
;with cte(iteration, ord, id, id2, deal) as
(
select ordered.*
, deal = (case when ord = 1 then 1 else 0 end)
from
(select 1 iteration,
ord = ROW_NUMBER() OVER (ORDER BY id),
st.*
FROM @sometable st) ordered
)
select * from CTE
union all
select
ordersinverted.nextIteration,
ordersinverted.ord,
ordersinverted.id,
ordersinverted.id2,
deal = (case when ord = 1 then 1 else 0 end)
from (
select
ROW_NUMBER() OVER (PARTITION BY ord ORDER BY iteration desc) as reversedIteration,
ROW_NUMBER() OVER (ORDER BY cte.id) as ord,
iteration + 1 as nextIteration,
cte.id,
cte.id2
from cte
where cte.deal = 0
) ordersinverted
Это дает мне ожидаемый результат для 3 итераций: Использовать row_number из результата CTE
Я бы очень хотел получить аналогичный результат и рекурсивно вызвать select. К сожалению, здесь есть подозрение на ошибку:
;with cte(iteration, ord, id, id2, deal) as
(
select ordered.*
, deal = (case when ord = 1 then 1 else 0 end)
from
(select 1 iteration,
ord = ROW_NUMBER() OVER (ORDER BY id),
st.*
FROM @sometable st) ordered
union all
select
ordersinverted.nextIteration,
ordersinverted.ord,
ordersinverted.id,
ordersinverted.id2,
deal = (case when ord = 1 then 1 else 0 end)
from (
select
ROW_NUMBER() OVER (PARTITION BY ord ORDER BY iteration desc) as reversedIteration,
ROW_NUMBER() OVER (ORDER BY cte.id) as ord,
iteration + 1 as nextIteration,
cte.id,
cte.id2
from cte
where cte.deal = 0
) ordersinverted
)
select * from CTE
Использовать row_number в результате CTE
Ой, извини. Это должно иметь формат вопроса: Итак, мой вопрос: это функция или ошибка?
Обратите внимание, что аналогичный запрос для Oracle будет работать так, как ожидалось:
with T (id,grp_id) as (
select 1 as id,1 as grp_id from dual union all
select 2 as id,1 as grp_id from dual union all
select 3 as id,1 as grp_id from dual union all
select 1 as id,2 as grp_id from dual union all
select 2 as id,2 as grp_id from dual union all
select 3 as id,2 as grp_id from dual )
,
rec (id,grp_id,rn) as (
select id, grp_id, row_number()over(partition by grp_id order by id) rn from T where grp_id=1
union all
select t.id, t.grp_id, row_number() over(partition by t.grp_id order by t.id) rn from T inner join rec on t.id=rec.id and t.grp_id=rec.grp_id+1
)
PS. Это работает аналогично, если использовать функции max() или min()...