Почему ROW_NUMBER OVER (столбец ORDER BY) возвращает другой порядок результатов, чем просто столбец ORDER BY? - PullRequest
3 голосов
/ 01 июня 2010

Я нахожусь на 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 */

1012 * возвращается *

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

Это полностью смущает меня и приводит к ошибке в нашем приложении, когда я получаю ту же запись в лагере, что и первый элемент на первой И второй странице нашего поиска.

Почему одно и то же предложение ORDER BY работает по-разному в выражении ROW_NUMBER OVER ()?

Ответы [ 3 ]

5 голосов
/ 01 июня 2010

ORDER BY this_.IsActive / * битовое поле * /

, так как это битовое поле, оно может быть только 0 или 1 ... Я предполагаю, что у вас есть много строк с этим битовым полем, равным 0 или 1, упорядочивание по которому не имеет смысла, что если 90% активно. ... в этом случае вы не правильно делаете заказ, потому что у вас нет второго заказа.

почему бы вам не выбрать что-то уникальное ... например, его_имя

или что по этому поводу?

ROW_NUMBER() OVER (ORDER BY this_.IsActive, this_.Name) 
3 голосов
/ 01 июня 2010

Вы ожидаете, что результат также будет упорядочен по имени, но в предложении ORDER BY будет только IsActive.

Природа SELECT основана на множествах, поэтому вам не следует полагаться на произвольные (но, казалось бы, правильные) упорядоченные результаты вашего запроса, если вы явно не определяете порядок.

3 голосов
/ 01 июня 2010

Это в основном случайное в обоих случаях, потому что битовое поле плохо для любого упорядочения (как отмечалось в SQL Menace). Они отдельно оцениваются механизмом БД, потому что они не имеют ничего общего друг с другом.

Примечание:

  • Внутренний ORDER BY только применяется к упорядочению значения ROW_NUMBER ().
  • Ваш вывод ORDER BY: только this_.IsActive
...