为什么ROW_NUMBER OVER(ORDER BY列)返回的结果顺序不仅仅是ORDER BY列?

时间:2010-06-01 19:14:27

标签: nhibernate tsql sql-server-2008 sql-order-by row-number

我在SQL Server 2008上,使用NHibernate作为持久层(尽管这个问题纯粹是SQL,我相信)。

我已将问题归结为以下SQL语句:

SELECT TOP 2
    this_.Id   as Id36_0_,
    this_.Name as Name36_0_,
    ROW_NUMBER() OVER (ORDER BY this_.IsActive) as MyOrder
FROM    Campsites this_
ORDER BY this_.IsActive  /* a bit field */

这是NH为检索分页结果集而生成的查询的一部分。上述陈述给出了以下结果:

Id36_0_ Name36_0_                       MyOrder
9806    Camping A Cassagnau                 1
8869    Camping a la ferme La Bergamotte    2

但是,如果我省略ROW_NUMBER()OVER(ORDER BY this_.IsActive) - 这是NH为在第一页上检索结果而生成的 - 我在结果中得到两个完全不同的表条目:

SELECT   TOP 2
    this_.Id   as Id36_0_,
    this_.Name as Name36_0_
    /* ROW_NUMBER() OVER(ORDER BY this_.IsActive) as MyOrder */
FROM     Campsites this_
ORDER BY this_.IsActive  /* a bit field */

返回

Id36_0_ Name36_0_
22876   Centro Vacanze Pra delle Torri
22135   Molecaten Park Napoleon Hoeve

这完全让我感到困惑,并导致我们的应用程序中出现一个错误,我将获得与第一页和第二页搜索相同的Campsite条目。

为什么相同的ORDER BY子句在ROW_NUMBER OVER()表达式中的工作方式不同?

3 个答案:

答案 0 :(得分:5)

ORDER BY this_.IsActive / * a bit field * /

因为那是一个位字段,它只能是0或1 ...我假设你有很多行,这个位字段为0或1排序它没有意义,如果90%是活跃的。 ..在这种情况下你没有真正订购,因为你没有第二次订购。

为什么不挑选一些独特的东西...也许是his_.Name例如

或者这个怎​​么样?

ROW_NUMBER() OVER (ORDER BY this_.IsActive, this_.Name) 

答案 1 :(得分:3)

在两个实例中它基本上是随机的,因为位字段对于任何排序都是不好的(正如SQL Menace所指出的那样)。它们由数据库引擎单独评估,因为它们彼此无关。

注意:

  • 内部ORDER BY 适用于ROW_NUMBER()值排序。
  • 您的输出ORDER BY仅 this_.IsActive

答案 2 :(得分:3)

您希望结果也按名称排序,但在ORDER BY子句中只有IsActive。

SELECT的本质是基于集合的,因此如果您没有明确定义订单,则不应依赖查询的任意(但看似正确)有序结果。