如何在SQL Server中使用OFFSET和Fetch without Order by

时间:2015-06-22 13:20:54

标签: sql-server sql-server-2012 sql-order-by fetch offset

我想在我的SQL server 2012查询中使用OFFSET和Fetch.But没有任何顺序。我不能使用order by.Because我的排序顺序将丢失。 我如何使用OFFSET和Fetch没有order by和行号以及我的查询中的位置? 我的2个选择表具有相同的结构。

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关键字处有语法错误。

5 个答案:

答案 0 :(得分:24)

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

select * from @TempTable ORDER BY(SELECT NULL) OFFSET 20 ROWS FETCH NEXT 50 ROWS ONLY

答案 1 :(得分:14)

您无法避免使用ORDER BY与OFFSET和FETCH所需的语法。

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

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

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

答案 2 :(得分:7)

通过向临时表变量

添加标识列
php.ini

为每一行添加一个自动递增数字,按照它们添加到临时表的顺序。插件不需要填充此列,因此插件可以保持原样。 然后可以通过以下方式将标识列用于订单:

    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

答案 3 :(得分:0)

经过研究并根据评论,明确和总结的答案是:"没有办法!"

但您可以使用row_number()保持排序顺序。所以 我提供了一个新的测试查询,它仍然是OFFSET和FETCH子句的临时表(final table)的排序顺序。

    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

答案 4 :(得分:0)

Offset / Fetch需要order by子句。如果您不想按任何顺序排序,可以使用CURRENT_TIMESTAMP来绕过此要求。我不确定但是,这应该根据存储顺序返回行(可能是聚簇索引)

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

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