在尝试在postgres中从服务器端实现分页时,我遇到了一个问题,即在使用limit和offset关键字时,您必须在唯一列上提供ORDER BY子句,可能是主键。
在我的情况下,我正在为Pkeys使用UUID生成,所以我不能依赖增加键的顺序。 ORDER BY pkey DESC - 可能不会导致最新的行总是在顶部。 所以我采用了创建日期列 - 时间戳列,它应该是唯一的。
但我的问题是,如果UI客户端想要按其他列排序,该怎么办?如果它可能并不总是一个唯一的列,我会使用ORDER BY user_column,created_dt DESC来保持postgres分页的可预测结果。
这是正确的方法吗?我不确定我是否采取正确的方式。请指教。
答案 0 :(得分:4)
我在一篇旧博文(在使用ORM的背景下)中谈到了这个确切的问题:
关于结合使用排序和分页的最后一点说明。一个问题 如果是ORDER BY子句,那么实现分页可能会产生奇怪的结果 不包括表示经验序列的字段 数据;排除顺序不能保证超出明确指定的顺序 在大多数(可能是所有)数据库引擎的ORDER BY子句中。一个 例如:如果您有100个订单,那么所有订单都完全相同 日期,您要求按此日期排序的此数据的第一页, 然后要求以相同方式排序的第二页数据,它是 完全有可能你会得到一些重复的数据 这两页。所以取决于查询和数据的分布 这是“可排序的”,总是包括一个很好的做法 唯一字段(如主键)作为sort子句中的最后一个字段 如果你正在实施分页。
http://psandler.wordpress.com/2009/11/20/dynamic-search-objects-part-5sorting/
答案 1 :(得分:2)
在某些情况下,可能无法使用将记录唯一标识为pkey或insertion_date的列的策略。
我有一个应用程序,用户在其中设置自己的网格查询,然后它可以简单地从多个表中放入任何列,并且可能没有唯一的标识符。
在可能有用的情况下,您可以使用rownum。您只需选择rownum并在over函数中使用他的排序。它会是这样的:
select col1, col2, col3, row_number() over(order by col3) from tableX order by col3
重要(over by *)与*匹配。因此,每次分页都会得到一致的结果。