Sql server 2008 r2 从sql表中按顺序递归地获取接下来的N行

Sql server 2008 r2 从sql表中按顺序递归地获取接下来的N行,sql-server-2008-r2,sql-server-2012,common-table-expression,Sql Server 2008 R2,Sql Server 2012,Common Table Expression,我有两张主桌和两张移动的桌子。主表中有记录,我通过执行存储过程将3行按顺序移动到移动的表中。所以每次执行存储过程时,它都应该检查下一组3行是否从主表中从上次移动发生的行中顺序读取并插入到移动的表中 select rowid from @main rowid ----------------------- 1 2 3 4 5 现在,当我执行查询时,它应该从主表中取出3行并插入到移动的表中。假设我运行查询5次,这就是我每次运行时移动的表所包含的内容 1,2,3 --"moved" table ha

我有两张主桌和两张移动的桌子。主表中有记录,我通过执行存储过程将3行按顺序移动到移动的表中。所以每次执行存储过程时,它都应该检查下一组3行是否从主表中从上次移动发生的行中顺序读取并插入到移动的表中

select rowid from @main
rowid
-----------------------
1
2
3
4
5
现在,当我执行查询时,它应该从主表中取出3行并插入到移动的表中。假设我运行查询5次,这就是我每次运行时移动的表所包含的内容

1,2,3 --"moved" table has these rows 1st time when I run the query
4,5,1 --"moved" table has these rows 2nd time when I run the query
2,3,4 --"moved" table has these rows 3rd time when I run the query
5,1,2 --"moved" table has these rows 4th time when I run the query
3,4,5 --"moved" table has these rows 5th time when I run the query
1,2,3 --"moved" table has these rows 6th time when I run the query
…因此顺序读取将继续。从上次运行结束的下一行开始按顺序读取

我已经问过了,但答案只起了部分作用。当主表中的值增长或不按顺序增长时,它不起作用


提前感谢您的帮助。

以下示例可能会为您提供一个起点。请注意,必须为要插入的值提供明确的顺序。表没有自然顺序,顺序也没有意义

-- Sample data.
declare @Template as Table ( TemplateValue VarChar(10), TemplateRank Int );
-- NB: TemplateRank values are assumed to start at zero and be dense.
insert into @Template ( TemplateValue, TemplateRank ) values
  ( 'one', 0 ), ( 'two', 1 ), ( 'three', 2 ), ( 'four', 3 );
declare @NumberOfTemplateValues Int = ( select Max( TemplateRank ) from @Template ) + 1;
select * from @Template;

declare @AccumulatedStuff as Table ( Id Int Identity, Value VarChar(10) );
declare @GroupSize as Int = 5;

-- Add a block of   GroupSize   rows to the   AccumulatedStuff .
declare @LastValue as VarChar(10) = ( select top 1 Value from @AccumulatedStuff order by Id desc );
declare @LastRank as Int = ( select TemplateRank from @Template where TemplateValue = @LastValue );
select @LastValue as LastValue, @LastRank as LastRank;

with Numbers as (
  select 1 as Number
  union all
  select Number + 1
    from Numbers
    where Number < @GroupSize ),
  RankedValues as (
    select TemplateValue, TemplateRank
      from @Template as T inner join
        Numbers as N on ( N.Number + Coalesce( @LastRank, @NumberOfTemplateValues - 1 ) ) % @NumberOfTemplateValues = T.TemplateRank )
  insert into @AccumulatedStuff
    select TemplateValue from RankedValues;

select * from @AccumulatedStuff;

-- Repeat.
set @LastValue = ( select top 1 Value from @AccumulatedStuff order by Id desc );
set @LastRank = ( select TemplateRank from @Template where TemplateValue = @LastValue );
select @LastValue as LastValue, @LastRank as LastRank;

with Numbers as (
  select 1 as Number
  union all
  select Number + 1
    from Numbers
    where Number < @GroupSize ),
  RankedValues as (
    select TemplateValue, TemplateRank
      from @Template as T inner join
        Numbers as N on ( N.Number + Coalesce( @LastRank, @NumberOfTemplateValues - 1 ) ) % @NumberOfTemplateValues = T.TemplateRank )
  insert into @AccumulatedStuff
    select TemplateValue from RankedValues;

select * from @AccumulatedStuff;

关键是要引用移动到移动/选定表的最后一条记录。它按预期工作。

没有ORDER BY子句,就没有顺序,SEQUIRATION也就没有意义。您希望使用哪一列来指定从@main获取值的顺序?只有一列,您不喜欢它提供的结果。主表是基表,只有一列RowID。移动表是也只有一个列RowID的目标表。我试图自上而下地读取行,并在到达表的末尾时再次从顶部开始读取-递归。只要我得到上面给定的输出,查询就可以是任何内容。主表只有该列RowID。感谢您的时间和代码HABO!非常感谢。只是希望它简单,不在显式循环中重复。对不起,我无法在我的帖子中清楚地解释我的问题,否则我相信你现在已经回答了。我自己弄明白了,把问题贴在下面,以防你想理解我上面说的话。对不起,我解释得不好。花了这么多时间后,我有点累了。非常感谢你!!!
DECLARE @main TABLE
(
    RowID INT IDENTITY(1,1),
    DataID INT
)
DECLARE @selected TABLE
(
    RowID INT IDENTITY(1,1),
    DataID INT
)

DECLARE @final TABLE
(
    RowID INT IDENTITY(1,1),
    DataID INT
)

INSERT INTO @main values (1),(2),(3),(4),(5),(6),(7)
--INSERT INTO @Selected values (1),(2),(3)
--INSERT INTO @Selected values (4),(5),(6)
--INSERT INTO @Selected values (7),(1),(2)
--INSERT INTO @Selected values (3),(4),(5)
INSERT INTO @Selected values (6),(7),(1)
--INSERT INTO @Selected values (2),(3),(4)
--INSERT INTO @Selected values (5),(6),(7)
--INSERT INTO @Selected values (1),(2),(3)

DECLARE 
    @LastDataID INT,
    @FinalCount INT

SELECT  
    TOP 1 
    @LastDataID = DataID 
FROM 
    @selected 
ORDER BY 
    RowID 
DESC 

INSERT INTO @final
    SELECT 
        TOP 3
        DataID
    FROM 
        @main
    WHERE
        DataID > @LastDataID 

SELECT @FinalCount = COUNT(1) FROM @final

IF (ISNULL(@FinalCount, 0 ) < 3)
BEGIN
    INSERT INTO @final
        SELECT 
            TOP (3 - @FinalCount)
            DataID
        FROM
            @main      
END

SELECT * FROM @final