Я играл вокруг отчетов, и оказалось, что row_number не работает в рекурсии.ROW_NUMBER не работает в CTE
!! Я упростил пример!
Из таблицы 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
В КТР выберите Все и маркируют первую запись должны быть исключены на следующей итерации:
;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 out of CTE result
Мне очень хотелось бы получить аналогичный результат и рекурсивно назвать 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 within CTE result
Ой, извините. У этого должен быть формат вопроса: Так что мой вопрос: Является ли это признаком или ошибкой?
Пожалуйста, обратите внимание, что аналогичный запрос для 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() ...
У меня действительно нет идеи о том, что вы пытаетесь достичь/выбрать, но я подозреваю, ваша проблема заключается в смешении подзапросов, row_number и рекурсивного cte, а SQL-сервер заказа выполняет запрос в Я думаю, что вы чрезмерно злоупотребляете запросом, делая это. Но поскольку я действительно не знаю, что вы на самом деле пытаетесь сделать, на основе ввода, я не могу указать лучше. Вместо того, чтобы пытаться сделать все в одном запросе, разделите его на более мелкие шаги. –
я бы попытался 1) создать CTE без row_number в нем 2) создать CTE2, который является Select CTE с row_number в нем. Я не уверен, что вы могли бы попробовать это – Cato
Спасибо за рекомендации о том, как обходиться. Это, однако, более подробно описывает проблему, существующую в MS SQL. Этот скрипт работает в Oracle. Будет ли добавить образец здесь – user6821153