Where子句中的SQL Row_Number()函数

我发现在where子句Row_Number()函数回答了一个问题。 当我尝试一个查询,我得到以下错误:

“消息4108,级别15,状态1,行1窗口函数只能出现在SELECT或ORDER BY子句中。

这是我试过的查询。 如果有人知道如何解决这个问题,请告诉我。

 SELECT employee_id FROM V_EMPLOYEE WHERE row_number() OVER ( ORDER BY employee_id ) > 0 ORDER BY Employee_ID 

为了解决这个问题,将你的select语句包装在一个CTE中,然后你可以对CTE进行查询,并在where子句中使用窗口函数的结果。

 WITH MyCte AS ( select employee_id, RowNum = row_number() OVER ( order by employee_id ) from V_EMPLOYEE ORDER BY Employee_ID ) SELECT employee_id FROM MyCte WHERE RowNum > 0 
 SELECT employee_id FROM ( SELECT employee_id, ROW_NUMBER() OVER (ORDER BY employee_id) AS rn FROM V_EMPLOYEE ) q WHERE rn > 0 ORDER BY Employee_ID 

请注意,这个filter是多余的: ROW_NUMBER()1开始并且总是大于0

 Select * from ( Select ROW_NUMBER() OVER ( order by Id) as 'Row_Number', * from tbl_Contact_Us ) as tbl Where tbl.Row_Number = 5 

我想你想要这样的东西:

 SELECT employee_id FROM (SELECT employee_id, row_number() OVER (order by employee_id) AS 'rownumber' FROM V_EMPLOYEE) TableExpressionsMustHaveAnAliasForDumbReasons WHERE rownumber > 0 

为了回应rexem的回答,关于内联视图还是CTE会更快,我重新使用了一个表I和每个人都可用的查询:sys.objects。

 WITH object_rows AS ( SELECT object_id, ROW_NUMBER() OVER ( ORDER BY object_id) RN FROM sys.objects) SELECT object_id FROM object_rows WHERE RN > 1 SELECT object_id FROM (SELECT object_id, ROW_NUMBER() OVER ( ORDER BY object_id) RN FROM sys.objects) T WHERE RN > 1 

生成的查询计划完全相同。 我希望在所有情况下,查询优化器都会提出相同的计划,至less可以用内联视图简单replaceCTE,反之亦然。

当然,在自己的系统上尝试自己的查询,看看是否有区别。

此外,where子句中的row_number()是堆栈溢出给出的答案中的常见错误。 逻辑row_number()在处理select子句之前不可用。 人们忘记了,当他们回答而没有testing答案时,答案有时是错误的。 (我自己犯了罪。)

使用CTE(SQL Server 2005+):

 WITH employee_rows AS ( SELECT t.employee_id, ROW_NUMBER() OVER ( ORDER BY t.employee_id ) 'rownum' FROM V_EMPLOYEE t) SELECT er.employee_id FROM employee_rows er WHERE er.rownum > 1 

使用内联视图/非CTE等效替代:

 SELECT er.employee_id FROM (SELECT t.employee_id, ROW_NUMBER() OVER ( ORDER BY t.employee_id ) 'rownum' FROM V_EMPLOYEE t) er WHERE er.rownum > 1 

根据OP的回答提问:

请看这个链接。 它有一个不同的解决scheme,这看起来工作的人提出的问题。 我试图找出这样的解决scheme。

使用SQL Server 2005中的ROW_NUMBER()OVER()对不同列进行sorting的分页查询

〜约瑟夫

“方法1”类似于OP从链接问题中的查询,而“方法2”类似于来自所选答案的查询。 您必须查看此答案中链接的代码,以查看实际发生的情况,因为所选答案中的代码已被修改以使其正常工作。 尝试这个:

 DECLARE @YourTable table (RowID int not null primary key identity, Value1 int, Value2 int, value3 int) SET NOCOUNT ON INSERT INTO @YourTable VALUES (1,1,1) INSERT INTO @YourTable VALUES (1,1,2) INSERT INTO @YourTable VALUES (1,1,3) INSERT INTO @YourTable VALUES (1,2,1) INSERT INTO @YourTable VALUES (1,2,2) INSERT INTO @YourTable VALUES (1,2,3) INSERT INTO @YourTable VALUES (1,3,1) INSERT INTO @YourTable VALUES (1,3,2) INSERT INTO @YourTable VALUES (1,3,3) INSERT INTO @YourTable VALUES (2,1,1) INSERT INTO @YourTable VALUES (2,1,2) INSERT INTO @YourTable VALUES (2,1,3) INSERT INTO @YourTable VALUES (2,2,1) INSERT INTO @YourTable VALUES (2,2,2) INSERT INTO @YourTable VALUES (2,2,3) INSERT INTO @YourTable VALUES (2,3,1) INSERT INTO @YourTable VALUES (2,3,2) INSERT INTO @YourTable VALUES (2,3,3) INSERT INTO @YourTable VALUES (3,1,1) INSERT INTO @YourTable VALUES (3,1,2) INSERT INTO @YourTable VALUES (3,1,3) INSERT INTO @YourTable VALUES (3,2,1) INSERT INTO @YourTable VALUES (3,2,2) INSERT INTO @YourTable VALUES (3,2,3) INSERT INTO @YourTable VALUES (3,3,1) INSERT INTO @YourTable VALUES (3,3,2) INSERT INTO @YourTable VALUES (3,3,3) SET NOCOUNT OFF DECLARE @PageNumber int DECLARE @PageSize int DECLARE @SortBy int SET @PageNumber=3 SET @PageSize=5 SET @SortBy=1 --SELECT * FROM @YourTable --Method 1 ;WITH PaginatedYourTable AS ( SELECT RowID,Value1,Value2,Value3 ,CASE @SortBy WHEN 1 THEN ROW_NUMBER() OVER (ORDER BY Value1 ASC) WHEN 2 THEN ROW_NUMBER() OVER (ORDER BY Value2 ASC) WHEN 3 THEN ROW_NUMBER() OVER (ORDER BY Value3 ASC) WHEN -1 THEN ROW_NUMBER() OVER (ORDER BY Value1 DESC) WHEN -2 THEN ROW_NUMBER() OVER (ORDER BY Value2 DESC) WHEN -3 THEN ROW_NUMBER() OVER (ORDER BY Value3 DESC) END AS RowNumber FROM @YourTable --WHERE ) SELECT RowID,Value1,Value2,Value3,RowNumber ,@PageNumber AS PageNumber, @PageSize AS PageSize, @SortBy AS SortBy FROM PaginatedYourTable WHERE RowNumber>=(@PageNumber-1)*@PageSize AND RowNumber<=(@PageNumber*@PageSize)-1 ORDER BY RowNumber -------------------------------------------- --Method 2 ;WITH PaginatedYourTable AS ( SELECT RowID,Value1,Value2,Value3 ,ROW_NUMBER() OVER ( ORDER BY CASE @SortBy WHEN 1 THEN Value1 WHEN 2 THEN Value2 WHEN 3 THEN Value3 END ASC ,CASE @SortBy WHEN -1 THEN Value1 WHEN -2 THEN Value2 WHEN -3 THEN Value3 END DESC ) RowNumber FROM @YourTable --WHERE more conditions here ) SELECT RowID,Value1,Value2,Value3,RowNumber ,@PageNumber AS PageNumber, @PageSize AS PageSize, @SortBy AS SortBy FROM PaginatedYourTable WHERE RowNumber>=(@PageNumber-1)*@PageSize AND RowNumber<=(@PageNumber*@PageSize)-1 --AND more conditions here ORDER BY CASE @SortBy WHEN 1 THEN Value1 WHEN 2 THEN Value2 WHEN 3 THEN Value3 END ASC ,CASE @SortBy WHEN -1 THEN Value1 WHEN -2 THEN Value2 WHEN -3 THEN Value3 END DESC 

OUTPUT:

 RowID Value1 Value2 Value3 RowNumber PageNumber PageSize SortBy ------ ------ ------ ------ ---------- ----------- ----------- ----------- 10 2 1 1 10 3 5 1 11 2 1 2 11 3 5 1 12 2 1 3 12 3 5 1 13 2 2 1 13 3 5 1 14 2 2 2 14 3 5 1 (5 row(s) affected RowID Value1 Value2 Value3 RowNumber PageNumber PageSize SortBy ------ ------ ------ ------ ---------- ----------- ----------- ----------- 10 2 1 1 10 3 5 1 11 2 1 2 11 3 5 1 12 2 1 3 12 3 5 1 13 2 2 1 13 3 5 1 14 2 2 2 14 3 5 1 (5 row(s) affected) 

如果需要dynamic添加条件,则可以使用存在于你的查询中:

 SELECT f0.* FROM FOO f0 WHERE EXISTS (SELECT f2.foo_id FROM (SELECT foo_id , ROW_NUMBER() OVER( PARTITION BY F1.BAR_ID ORDER BY F1.AMOUNT) rk FROM foo f1 )f2 WHERE f0.foo_id=f2.foo_id AND rk =2 -- your condition on row_number goes here ); 
 WITH MyCte AS ( select employee_id, RowNum = row_number() OVER (order by employee_id) from V_EMPLOYEE ) SELECT employee_id FROM MyCte WHERE RowNum > 0 ORDER BY employee_id