将限制和偏移量应用于MS SQL server 2008查询
我需要在MSSQL server 2008中将将限制和偏移量应用于MS SQL server 2008查询,sql,sql-server,sql-server-2008,tsql,Sql,Sql Server,Sql Server 2008,Tsql,我需要在MSSQL server 2008中将限制和偏移应用于原始查询(不进行修改) 假设原始查询是: SELECT * FROM energy_usage (但它可以是任意选择查询) 到目前为止,我就是这么想的: 1。它执行我需要的操作,但查询会生成我不需要的extra列行数 WITH OrderedTable AS ( SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS row_number, * FROM energy_usage )
限制
和偏移
应用于原始查询(不进行修改)
假设原始查询是:
SELECT * FROM energy_usage
(但它可以是任意选择查询)
到目前为止,我就是这么想的:
1。它执行我需要的操作,但查询会生成我不需要的extra列行数
WITH OrderedTable AS
(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS row_number, * FROM energy_usage
)
SELECT * FROM OrderedTable WHERE row_number BETWEEN 1 AND 10
2.由于某些原因,此选项不起作用,并返回以下错误
SELECT real_sql.* FROM (
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS row_number, * FROM (SELECT * FROM energy_usage) as real_sql) as subquery
WHERE row_number BETWEEN 1 AND 10
更常见的情况是:
SELECT real_sql.* FROM (
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS row_number, * FROM (real sql query) as real_sql) as subquery
WHERE row_number BETWEEN {offset} + 1 AND {limit} + {offset}
错误:
列前缀“real_sql”与表名或别名不匹配
查询中使用的名称
只需不将其放入
选择列表:
WITH OrderedTable AS
(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS row_number, *
FROM energy_usage
)
SELECT col1, col2, col3 FROM OrderedTable WHERE row_number BETWEEN 1 AND 10;
SELECT*
是常见的反模式,无论如何都应该避免。另外,orderby(选择1)
不能保证执行之间的排序稳定
第二,如果只需要十行,请使用:
SELECT TOP 10 *
FROM energy_usage
ORDER BY ...
不幸的是,你不会得到像这样好的东西
这将解决问题
DECLARE @offset INT = 1;
DECLARE @limit INT = 10;
WITH Filtered AS (
SELECT TOP (@offset + @limit) *
FROM energy_usage
ORDER BY 1 ASC
), Results AS (
SELECT TOP (@limit) *
FROM Filtered
ORDER BY 1 DESC
)
SELECT *
FROM Results
ORDER BY 1 ASC;
谢谢你的回答。不幸的是,我不能使用您的第一个建议,因为原始查询必须是未修改的(原始查询是一个任意的SELECT语句),而且我需要传递偏移量和限制(1和10只是一个示例)。更新了初始问题。如果请求的范围超出可用行数,则偏移量将无法正常工作。例如,一个表有10行,偏移量为50(不应返回任何行)。@Chamika只有当orderby1-具有唯一值时,该解决方案才能正常工作。但是由于原始查询是任意的,我们不能依赖它。
DECLARE @offset INT = 1;
DECLARE @limit INT = 10;
WITH Filtered AS (
SELECT TOP (@offset + @limit) *
FROM energy_usage
ORDER BY 1 ASC
), Results AS (
SELECT TOP (@limit) *
FROM Filtered
ORDER BY 1 DESC
)
SELECT *
FROM Results
ORDER BY 1 ASC;