如何在 SQL 服务器中使用 OFFSET 和 Fetch without Order by
How to use OFFSET and Fetch without Order by in SQL Server
我想在我的 SQL 服务器 2012 query.But 中使用 OFFSET 和 Fetch,没有任何顺序 by.I 不能使用顺序 by.Because 我的排序顺序将会丢失。
如何在没有顺序和行号以及查询位置的情况下使用 OFFSET 和 Fetch?
我的 2 个 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 关键字处存在语法错误。
经过研究并根据评论,明确而总结的答案是:"There is no way!"
但您可以使用 row_number() 保留排序顺序。所以
我提供了一个新的测试查询,它保持 temp table(final table) 的排序顺序,带有 OFFSET 和 FETCH 子句。
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
通过向临时 table 变量添加标识列
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
为每一行添加一个自动递增的数字,按照它们添加到临时文件的顺序 table。插页不需要填充此列,因此插页可以保持原样。
然后可以将标识列用于订单:
select * from @TempTable Order by rownr OFFSET 20 ROWS FETCH NEXT 50 ROWS ONLY
您无法避免使用带有 OFFSET 和 FETCH 的 ORDER BY 的必需语法。
但是,可以取消关联您必须提供的 ORDER BY 子句,以便从记录插入过程创建的自然 table 顺序执行分页。
使用下面的解决方案,您不必对基础 table 或
进行任何更改
Select 0 as TempSort, T.* From MyTable T ORDER BY TempSort OFFSET 2 ROWS FETCH NEXT 3 ROWS
提供虚拟 ORDER BY 子句的方法更简单:
select * from @TempTable ORDER BY(SELECT NULL) OFFSET 20 ROWS FETCH NEXT 50 ROWS ONLY
Offset/Fetch 需要一个 order by 子句。如果您不想按任何顺序进行,可以使用 CURRENT_TIMESTAMP 绕过此要求。我不确定,但是,这应该 return 基于存储顺序的行(可能是聚簇索引)
因此将您的代码更改为此应该可以解决问题 -
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
我想在我的 SQL 服务器 2012 query.But 中使用 OFFSET 和 Fetch,没有任何顺序 by.I 不能使用顺序 by.Because 我的排序顺序将会丢失。 如何在没有顺序和行号以及查询位置的情况下使用 OFFSET 和 Fetch? 我的 2 个 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 关键字处存在语法错误。
经过研究并根据评论,明确而总结的答案是:"There is no way!"
但您可以使用 row_number() 保留排序顺序。所以 我提供了一个新的测试查询,它保持 temp table(final table) 的排序顺序,带有 OFFSET 和 FETCH 子句。
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
通过向临时 table 变量添加标识列
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
为每一行添加一个自动递增的数字,按照它们添加到临时文件的顺序 table。插页不需要填充此列,因此插页可以保持原样。 然后可以将标识列用于订单:
select * from @TempTable Order by rownr OFFSET 20 ROWS FETCH NEXT 50 ROWS ONLY
您无法避免使用带有 OFFSET 和 FETCH 的 ORDER BY 的必需语法。
但是,可以取消关联您必须提供的 ORDER BY 子句,以便从记录插入过程创建的自然 table 顺序执行分页。
使用下面的解决方案,您不必对基础 table 或
进行任何更改Select 0 as TempSort, T.* From MyTable T ORDER BY TempSort OFFSET 2 ROWS FETCH NEXT 3 ROWS
提供虚拟 ORDER BY 子句的方法更简单:
select * from @TempTable ORDER BY(SELECT NULL) OFFSET 20 ROWS FETCH NEXT 50 ROWS ONLY
Offset/Fetch 需要一个 order by 子句。如果您不想按任何顺序进行,可以使用 CURRENT_TIMESTAMP 绕过此要求。我不确定,但是,这应该 return 基于存储顺序的行(可能是聚簇索引)
因此将您的代码更改为此应该可以解决问题 -
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