【问题标题】:mysql - Find page of result record in paginationmysql - 在分页中查找结果记录的页面
【发布时间】:2013-09-12 16:59:24
【问题描述】:

想象一下我们使用分页来拆分并显示这样的mysql结果, 按自动增量 ID 和日期排序:

SELECT name FROM members ORDER BY id DESC, date DESC LIMIT $start, $len

我们使用 php 在其下方显示该结果和页面导航链接。

我们如何找到记录 ID 号 x 在该结果的哪个页面中,因此我们为该页面设置页码并显示该页面,最终用户无需单击导航并找到它?

【问题讨论】:

  • 请问那个数据库的表怎么样?
  • name:varchar(100),date:DATETIME 和 id:INT PRIMARY AUTOINC.

标签: php mysql pagination matching


【解决方案1】:

首先获取记录总数。

select count(*) as total from members; 

在记录列表中查找行成员'x'的编号

select count(*) oneLess from members where id < (select id from members where name='x');

上面的查询从 x 中返回 oneLess 的记录号。即'x'是oneLess+1

现在计算页码。

$asc_page_no =  floor((($oneLess+1)/$total)*$len);
$total_pages = floor($total/$len);
$page_no = $total_pages - $asc_page_no; //reverse the page looking direction

然后计算$start

$start = $page_no * $len;

【讨论】:

  • 这有一些错误,因为我们使用 DESC 而不是 ASC,应该从页尾开始计算。
  • @exim 这需要对代码进行非常小的更改。我更新了我的答案。
【解决方案2】:

@Bere 有一个不错的解决方案,但问题是您的 PRIMARY KEY 是 autoinc 一个,因此 2 个 id 可能不是连续的。

您应该添加一列以放置您可以控制的数字。

在@Bere的响应中使用程序但不使用主键,使用新列。

【讨论】:

  • 但它可能是大量记录,我应该使用该索引列。
  • 巨大是什么意思?如果数字很大,ID应该也不是吗?
  • 在每个 INSERT 命令期间需要额外的计算。还可以想象最终用户在毫秒内向数据库发送了几个 INSERT,那么我们如何计算数字并将其设置为新列?那么我们应该锁定数据库,这不是很好的解决方案。
  • 触发器会为你做这件事。你只需要找到 MAX() + 1 并且你的插入应该尊重 ACID 属性,所以它应该没有问题。您的数据库可能出现问题的唯一方法是,如果您有一个非常大的应用程序,但在这种情况下,您不会使用 mysql 来管理这么多的连接
【解决方案3】:

首先,我们需要确定所需行所在的页码:

SELECT d.myRowSerial, FLOOR((d.myRowSerial-1)/10) AS pageNumber
-- Say, 10 is per page;
FROM (
    SELECT *, @rownum:=@rownum + 1 AS myRowSerial 
    FROM myTable, (SELECT @rownum:=0) AS nothingButSetInitialValue 
    WHERE 1=1 -- Optional: filter if required, otherwise, omit this line;
    ORDER BY AnyColumn -- Apply the order you like; 
) d
WHERE d.myColumn = 'Anything'; -- If you like to limit it to only
-- for any specific row(s), similar to the *MAIN query.

第 1 页的 pageNumber==0,第 2 页的 pageNumber==1,依此类推..... 那么我们就可以通过简单的计算来简单地计算出OFFSET数:

$offset = $myRowSerial * $perPage;

现在我们可以将这个 $offset 值用于我们的 MAIN 查询。

【讨论】:

    【解决方案4】:

    由于 Reza Mamun 提供了他的解决方案,它的效果非常好……我还想创建 SELECT HTML 元素来在页面之间导航。这需要另一种方法。

    为了创建 SELECT 元素,我使用带有 'name' 和 'value' 键的数组,所以 SQL 查询看起来是这样的:

     $qry='
    SELECT d.RowNumber, FLOOR( ( d.RowNumber ) / %s ) AS value, d.name 
        FROM( 
                SELECT  %s AS ID, 
                            %s AS name,
                            @rownum:=@rownum+1 AS RowNumber 
                    FROM    %s, 
                            ( SELECT @rownum:=-1 ) AS Initialize 
                    %s 
                    %s 
             ) AS d
        WHERE d.Rownumber MOD %s = 0';
    
    
    $sqry   = sprintf( $qry, $pagelength, $this->_tableindex, $sort_field, $this->_tablename, $cond, $sql_order, $pagelength );
    

    query 使用 WHERE 过滤(由用户通过表单定义),排序 ORDER BY(由 used 选择)。我认为变量和属性的含义是可以区分的。该解决方案适用于(几乎)通用数据分页和用户定义的页面长度。

    【讨论】:

      猜你喜欢
      • 2013-11-08
      • 2012-02-23
      • 2011-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多