想象一下,我们使用分页来拆分和显示这样的MySQL结果,按自动注册ID和日期排序:
SELECT name FROM members ORDER BY id DESC, date DESC LIMIT $start, $len
我们使用PHP在其下方显示该结果和页面导航链接。
我们如何找到记录 ID 号 x 在该结果的哪个页面,以便我们将页码设置为该页面并显示该页面,最终用户无需单击导航即可找到它?
首先获取记录总数。
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;
@Bere有一个
很好的解决方案,但问题是您的主键是自动键,因此 2 个 id 可能不是连续的。
您应该添加一个列来放置一个可以控制的数字。
在@Bere的响应中使用程序但不使用主键后,使用新列。
首先,我们需要确定所需行所在的页码:
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 页的页码==1,依此类推.....然后我们可以通过简单的计算简单地计算 OFFSET 数:
$offset = $myRowSerial * $perPage;
现在我们可以将此$offset值用于主查询。
当礼萨·马蒙提供他的解决方案时,它的效果非常棒......我还想创建 SELECT HTML 元素以在页面之间导航。这需要另一种方法。
为了创建 SELECT 元素,我使用带有"名称"和"值"键的数组,因此 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 );
查询适用于按 WHERE 过滤(由用户通过表单定义),排序 ORDER BY(由使用选择)。我认为变量和属性的含义是可以区分的。此解决方案适用于(几乎)通用数据分页和用户定义的页面长度。