【发布时间】:2016-09-12 07:30:07
【问题描述】:
我正在研究报告,但似乎 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 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 以及 order sql服务器在其中执行查询。我认为您这样做会使查询不必要地复杂化。但是由于我真的不知道您实际上要做什么,因此根据输入,我无法更好地指定。与其尝试在单个查询中完成所有操作,不如将其拆分为更小的步骤。
-
我想尝试的是 1)创建没有 row_number 的 CTE 2)创建 CTE2,它是 CTE 的 Select,其中包含 row_number。不知道你能不能试试
-
感谢有关如何解决的建议。然而,这更能描述 MS SQL 中存在的问题。该脚本在 Oracle 中确实有效。将在此处添加示例一
标签: sql-server common-table-expression with-statement row-number