Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 分页:找出项目所在的页面(给定主键和排序顺序)_Sql_Postgresql_Pagination - Fatal编程技术网

Sql 分页:找出项目所在的页面(给定主键和排序顺序)

Sql 分页:找出项目所在的页面(给定主键和排序顺序),sql,postgresql,pagination,Sql,Postgresql,Pagination,假设我这样做分页: SELECT article_id, article_content FROM articles ORDER BY article_rating OFFSET (page - 1) * items_per_page LIMIT items_per_page; SELECT article_id, article_content FROM articles ORDER BY article_rating, arti

假设我这样做分页:

SELECT article_id, 
       article_content 
FROM articles 
ORDER BY article_rating 
OFFSET (page - 1) * items_per_page 
LIMIT items_per_page;
SELECT article_id, 
       article_content 
FROM articles 
ORDER BY article_rating,
         article_id
OFFSET (page - 1) * items_per_page 
LIMIT items_per_page;
Select ceiling(rowNumber/items_per_page)
  from (
SELECT article_id
     , article_content 
     , row_number() over (order by article_rating, article_id)
       as rowNumber
  FROM articles 
 where article_rating <= (select article_rating
                            from articles
                           where article_id = 'xxxx' )
 ORDER BY article_rating,
          article_id
       ) x
 where article_id = 'xxxx'
我有一个关于文章等级的索引,文章id

我的问题是:如果我想知道一篇文章在哪一页,最有效的方法是什么

a知道这篇文章吗

b知道排序是按物品的顺序排列的吗

它需要高效,因为我将经常进行这种类型的查询

如果它不仅能说出页码,还能说出该页上的所有文章,那就更好了

因此,例如,如果所有文章都按评级排序,并且每十篇文章都放在不同的页面上,那么我想知道ID为839的文章放在哪一页上

我正在使用PostgreSQL 8.4,如有必要,我愿意更新

谢谢大家!

编辑:

正如下面的评论所指出的,我的查询应该是这样的:

SELECT article_id, 
       article_content 
FROM articles 
ORDER BY article_rating 
OFFSET (page - 1) * items_per_page 
LIMIT items_per_page;
SELECT article_id, 
       article_content 
FROM articles 
ORDER BY article_rating,
         article_id
OFFSET (page - 1) * items_per_page 
LIMIT items_per_page;
Select ceiling(rowNumber/items_per_page)
  from (
SELECT article_id
     , article_content 
     , row_number() over (order by article_rating, article_id)
       as rowNumber
  FROM articles 
 where article_rating <= (select article_rating
                            from articles
                           where article_id = 'xxxx' )
 ORDER BY article_rating,
          article_id
       ) x
 where article_id = 'xxxx'
请参见下面的第二个查询,它比第一个查询好得多

假设Postgres 9.0或更高版本,您必须使用窗口函数在每个项目上获取行号。然后将特定文章的行号除以每页的项目数,然后四舍五入得到页码。唯一可以提高效率的方法是,至少不要查询问题文章后面的文章。你会得到这样的结果:

SELECT article_id, 
       article_content 
FROM articles 
ORDER BY article_rating 
OFFSET (page - 1) * items_per_page 
LIMIT items_per_page;
SELECT article_id, 
       article_content 
FROM articles 
ORDER BY article_rating,
         article_id
OFFSET (page - 1) * items_per_page 
LIMIT items_per_page;
Select ceiling(rowNumber/items_per_page)
  from (
SELECT article_id
     , article_content 
     , row_number() over (order by article_rating, article_id)
       as rowNumber
  FROM articles 
 where article_rating <= (select article_rating
                            from articles
                           where article_id = 'xxxx' )
 ORDER BY article_rating,
          article_id
       ) x
 where article_id = 'xxxx'
编辑以回应评论中的问题。是的,我刚刚意识到有更好的方法。通过运行count*,我们只遍历索引

Select ceiling(count(*)/items_per_page)
  FROM articles 
 where article_rating < (select article_rating
                           from articles
                          where article_id = 'xxxx' )
    or ( article_rating = (select article_rating
                           from articles
                          where article_id = 'xxxx' )
        and article_id <= 'xxxx')

通常我们不喜欢WHERE子句中的OR子句,因为它们会降低性能,但这一条应该是相当安全的,因为如果文章评级被索引,每个子句都应该是可优化的。

如果有多个项目具有相同的文章评级,这可能会特别棘手-它可能会出现在许多不同的页面上。@Damien_不信者:你是对的,我应该按文章评级排序,如果两个或更多的文章具有相同的评级,文章将获得确定的顺序。非常感谢您的快速回复。我担心会归结为这样的事情。页码越高,查询速度可能会越慢,不是吗?有什么我可以做的,不让执行时间取决于文章的页面吗?谢谢你的编辑。不幸的是,我在接下来的几天里无法访问我的PostgreSQL机器,所以我现在无法测试它的实际运行情况。但是我想如果它只需要遍历索引,即使页码很高,它也应该非常快;我对这个假设正确吗?