Sql server 如何在SQL Server中使用无订单的偏移和提取

Sql server 如何在SQL Server中使用无订单的偏移和提取,sql-server,sql-server-2012,sql-order-by,fetch,offset,Sql Server,Sql Server 2012,Sql Order By,Fetch,Offset,我想在我的SQL server 2012查询中使用偏移量和提取。但是没有任何排序依据。我不能使用排序依据。因为我的排序顺序将丢失。 如果查询中没有order by和行号以及where,如何使用偏移量和Fetch? 我的两个select表具有相同的结构 INSERT INTO @TempTable [some columns] select [some columns] from table1 order by col1 INSERT INTO @TempTable [same column

我想在我的SQL server 2012查询中使用偏移量和提取。但是没有任何排序依据。我不能使用排序依据。因为我的排序顺序将丢失。 如果查询中没有order by和行号以及where,如何使用偏移量和Fetch? 我的两个select表具有相同的结构

INSERT INTO @TempTable [some columns]  
select [some columns] from table1 order by col1 
INSERT INTO @TempTable [same columns]
select [some columns] from table2 order by col2
select * from @TempTable OFFSET 20 ROWS FETCH NEXT 50 ROWS ONLY

此查询在OFFSET关键字处有语法错误。

经过研究并根据评论,明确而概括的答案是:没有办法

但您可以保留带有行号的排序顺序。所以 我提供了一个新的经过测试的查询,该查询使用OFFSET和FETCH子句保持temp tablefinal表的排序顺序

    INSERT INTO @TempTable [some columns]  
    select [some columns],row_number() OVER (order by col1) row from table1 order by col1 

    declare @maxrow int
    select @maxrow=max(rn) from @TempTable

    INSERT INTO @TempTable [same columns]
    select [some columns],((row_number() OVER (order by col2)) + @maxrow) row from table2 order by col2

    select * from @TempTable Order by row  OFFSET 20 ROWS FETCH NEXT 50 ROWS ONLY

通过向临时表变量添加标识列

    declare @TempTable table([some columns], rownr int identity(1,1) )

    INSERT INTO @TempTable [some columns]  
    select [some columns] from table1  order by col1 

    INSERT INTO @TempTable [same columns]
    select [some columns] from table2 order by col2
将为每一行添加一个自动递增的数字,按照它们添加到临时表的顺序。插入内容不需要填充此列,因此插入内容可以保持原样。 然后,可以通过以下方式将标识列用于订单:

 select * from @TempTable Order by rownr OFFSET 20 ROWS FETCH NEXT 50 ROWS ONLY

您无法避免使用orderby所需的语法以及OFFSET和FETCH

但是,可以解除ORDER BY子句的关联,您必须提供该子句,以便从记录插入过程创建的自然表顺序执行分页

使用下面的解决方案,您也不必对基础表进行任何更改

Select 0 as TempSort, T.* From MyTable T ORDER BY TempSort OFFSET 2 ROWS FETCH NEXT 3 ROWS

提供虚拟ORDER BY子句还有一种更简单的方法:

从@TENTABLE ORDER BYSELECT NULL OFFSET 20行中选择*仅取下50行
Offset/Fetch需要order by子句。如果您不想按任何顺序操作,可以使用当前的_时间戳来绕过此要求。我不确定,但是,这可能会根据存储聚集索引的顺序返回行

因此,将代码更改为此应该可以解决问题-

INSERT INTO @TempTable [some columns]  
select [some columns] from table1 order by col1 
INSERT INTO @TempTable [same columns]
select [some columns] from table2 order by col2
select * from @TempTable **order by current_timestamp** OFFSET 20 ROWS FETCH NEXT 50 ROWS ONLY

OFFSET-FETCH仅应用于有序集。在SQL表中没有固有的顺序,如果要指定顺序,则必须使用order BY。因此,您想要的是不可能的。是的,当然,尽管我不理解您的意思,因为我的排序顺序将丢失。表中没有要丢失的固有排序顺序。您需要指定一个order BY,因为不能保证当前顺序始终是返回结果的顺序。order BY 1不是按标量值1排序,而是按顺序位置排序。这意味着它将按结果集中的第一列排序。这是一个可怕的习惯。当您使用序号位置时,当select中的列的顺序更改并且您不更新序号引用时,您可能会遇到将来的错误。注意:除非指定order BY子句,否则结果集中返回行的顺序不受保证。这是一个很好的纯SQL select修复程序,没有临时表、标识列或其他SQL Server详细信息。对于那些认为RDBMS供应商强迫我们使用ORDER是正确的人来说:你错了!简单即时分页应该得到数据集的偏移量n和偏移量m之间的一帧,而不管平台如何排序。请记住,对于特定的供应商,这些数据集始终以相同的顺序返回行,即使没有指定order BY!强迫我们使用ORDER BY并不总是正确的。你是一个SQL忍者!什么在SQL Server 2017上不起作用?错误?错误的结果?到目前为止,我们在SQL Server版本中使用它没有任何问题。我发现这会在查询之间创建不一致的顺序。因此,如果您将此用于分页,您可能会(例如)获得同一行两次,等等。在阅读您的答案后,必须从接受的答案中删除我的向上投票