【问题标题】:How to select records that ordered by DESC?如何选择按DESC排序的记录?
【发布时间】:2016-10-13 09:11:49
【问题描述】:
SET @LatestRowNum = 2; 
WITH OrderedOrders AS  
( 
    SELECT 
        ROW_NUMBER() OVER(order by ID desc) AS Rownum, 
        *
    FROM  someTable WITH(NOLOCK)                
    ORDER BY ID DESC
)
SELECT *
FROM
OrderedOrders WHERE Rownum = @LatestRowNum

上面的查询把我扔了

消息 1033,第 15 级,状态 1,第 17 行 ORDER BY 子句在视图、内联函数、派生表、子查询和公用表表达式中无效,除非还指定了 TOP、OFFSET 或 FOR XML。

如何实现有时我期待最后一条记录或有时是倒数第二条记录的目标?

【问题讨论】:

  • 为什么不直接使用行号呢?
  • 您可以在Rownum 的主查询中订购。实际上,您的 CTE 中不需要额外的 ORDER BY 来使您的 ROW_NUMBER() 工作,它已经包含在其中。
  • 为什么要订购,而您检索的只是一行?
  • @bastos.sergio 我同意你的看法。

标签: sql-server


【解决方案1】:

您不需要内部ORDER 子句,因为您在ROW_NUMBER() 中使用了ORDER 子句。

试试这个

SET @LatestRowNum = 2; 
WITH OrderedOrders AS  
( 
    SELECT ROW_NUMBER() OVER(order by ID desc) AS Rownum,*
    FROM someTable WITH(NOLOCK)                
)
SELECT * FROM
OrderedOrders WHERE Rownum = @LatestRowNum

【讨论】:

【解决方案2】:

如果查询只返回一条记录,则除了 row_number 之外不需要排序。但 您可以尝试添加TOP 关键字。请注意,TOP 100 PERCENT 不起作用。您可以尝试添加TOP 9999999(最大)可能的数字。
此外,OP 中的一些评论表明,由于ROW_NUMBER 中的ORDER BY 而无需添加订单,但ROW_NUMBER 并不总是对行进行排序(参考:https://msdn.microsoft.com/en-in/library/ms186734.aspx。检查一般备注)。

无法保证查询返回的行使用 每次执行时,ROW_NUMBER() 的顺序都完全相同

您可以参考几篇有用的文章:
http://blog.sqlauthority.com/2010/08/23/sql-server-order-by-does-not-work-limitation-of-the-views-part-1/

Create a view with ORDER BY clause


编辑:
其他解决方案是在 TOP 关键字中使用变量而不是常量。 例如TOP (@T) PERCENT。

declare @t as tinyint  = 100
declare @tbl as table (num1 int,num2 int)
insert into @tbl values (7,1),(2,7),(4,6),(6,4), (7,1),(2,7),(4,6),(6,4)
select * from(select top 100 percent * from @tbl order by num1) t 
select * from(select top (@t) percent * from @tbl order by num1) t

在上面的例子中,最后一个查询给出了预期的结果。如果 TOP 关键字中有变量,则 SQL 假定可能有任何值,因此它将始终考虑它而不是忽略它。

【讨论】:

  • TOP 100 PERCENT 在 SQL Server 中工作,我绝不建议添加 TOP largest_number_ever。而且,ROW_NUMBER() 中的 ORDER BY 确实不能保证行将按排序顺序返回,但用户只是试图根据 ROW_NUMBER() 的值返回单行(在这种情况下排序是毫无意义),因为ROW_NUMBER() 是唯一的(如果你没有使用PARTITION BY)
  • @RaduGheorghiu :排序很重要,因为我只期待最新记录或第二个最新记录。如果某些旧数据被排序为第一行,那么显然它不符合我的要求
  • @RaduGheorghiu 尝试以下代码并检查执行计划。计划中不会有排序。插入 tbl1 值 (7,1),(2,7),(4,6),(6,4) 创建视图 vTmp 作为 select top 100 percent * from tbl1 order by num1; 或将@tbl声明为表(num1 int,num2 int)插入@tbl值(7,1),(2,7),(4,6),(6,4) , (7,1),(2,7),(4,6),(6,4) select * from(select top 100 percent * from @tbl order by num1) t
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多