postgresql, нечетное поведение OFFSET / LIMIT (порядок записей) - PullRequest
1 голос
/ 22 февраля 2012

так что в основном у меня есть эта область (sql):

scope.to_sql
=> "SELECT  \"offers\".* FROM \"offers\" INNER JOIN \"cities_offers\" ON \"offers\".\"id\" = \"cities_offers\".\"offer_id\" WHERE \"cities_offers\".\"city_id\" = 2 AND \"offers\".\"category_id\" IN (2) AND (offers.category_id is NOT NULL) ORDER BY offers.discount desc LIMIT 25 OFFSET 0"

Почему-то порядок записей отличается для вышеупомянутого запроса и тот же без LIMIT и OFFSET:

   scope[6]
=> #<Offer id: 8629 ...

scope.except(:offset, :limit)[6]
=> #<Offer id: 8729 ...

записи 8629 и 8729 имеют одно и то же значение discount (атрибут, который я упорядочиваю).

Не могли бы вы посоветовать, можно ли при таких обстоятельствах сохранять порядок тех же записей?

1 Ответ

6 голосов
/ 22 февраля 2012

Реляционные базы данных основаны на множествах и, следовательно, изначально неупорядочены; порядок записей в наборе результатов определяется только предложением ORDER BY. Если две строки имеют одинаковые значения для выражения в предложении ORDER BY, то выполнение одного и того же запроса дважды может вернуть эти строки в разные позиции; изменение запроса путем добавления LIMIT и OFFSET только усугубляет ситуацию, делая более вероятным другой порядок.

Если вы хотите, чтобы база данных предоставляла вам строки в определенном порядке, вы должны полностью указать порядок в своем предложении ORDER BY. Вы должны добавить больше к вызову order в своей области:

...order('offers.discount desc, offers.created_at asc')

или что-то в этом роде в зависимости от того, какой именно заказ вам нужен.

...