基于名称的Next和Previous MySQL行

Nig*_*ICU 3 php mysql row next

我有一张关于人员详情的表格.我想根据个人的姓氏创建一个Next/Previous链接.由于人员未按字母顺序添加,因此根据其ID选择下一行或上一行不起作用.

这是一个很大的表 - 相关的字段是id,name_l和name_f.我想通过name_l订购个人的姓氏.

我将如何完成这项任务?

谢谢!

编辑 这将在人员详细信息页面上使用,结果将生成基于当前行的数据库中下一个/ prev条目的链接(按姓氏排序).例如,如果我正在查看Joe Hammer,则Next链接将链接到Frank Ingram.

最终代码

感谢Daniel,这是我最终的工作:

首先,我将增量设置为0:$ i = 0.然后,在使用while循环遍历记录,我将其增加1 = $ i ++.然后我链接到该特定条目的详细信息页面:

<a href="details.php?id=<?php echo $member['id'];?>&amp;row=<?php echo $i;?>">Details</a>
Run Code Online (Sandbox Code Playgroud)

在Details页面上,我使用以下SQL来选择下一条记录:

$row = $_GET['row'];
$getNext = mysql_query("SELECT * FROM members ORDER BY name_l, id LIMIT ".$row.", 1");
$next = mysql_fetch_assoc($getNext);
$nextLink = $row + 1;
Run Code Online (Sandbox Code Playgroud)

最后,链接:

<a href="member_details.php?id=<?php echo $next['id'];?>&amp;row=<?php echo $nextLink;?>"><?php echo $next['name_l'] . ", " . $next['name_f'];?></a>
Run Code Online (Sandbox Code Playgroud)

Dan*_*llo 9

首先,确保您的name_l列已编入索引.然后你可以简单地使用ORDER BYLIMIT子句如下:

SELECT * FROM personnel ORDER BY name_l, id LIMIT 0, 1;
Run Code Online (Sandbox Code Playgroud)

只需递增LIMIT子句中的0值即可选择有序集中的下一条记录.因此用于LIMIT 1, 1获得第二个记录,LIMIT 2, 1第三个记录等.

要创建索引,name_l可以使用以下CREATE INDEX命令:

CREATE INDEX ix_index_name ON personnel (name_l);
Run Code Online (Sandbox Code Playgroud)

测试用例:

CREATE TABLE personnel (
   id int not null primary key, 
   name_l varchar(10), 
   name_f varchar(10)
);

CREATE INDEX ix_last_name_index ON personnel (name_l);

INSERT INTO personnel VALUES (1, 'Pacino', 'Al');
INSERT INTO personnel VALUES (2, 'Nicholson', 'Jack');
INSERT INTO personnel VALUES (3, 'De Niro', 'Robert');
INSERT INTO personnel VALUES (4, 'Newman', 'Paul');
INSERT INTO personnel VALUES (5, 'Duvall', 'Robert');
Run Code Online (Sandbox Code Playgroud)

结果:

SELECT * FROM personnel ORDER BY name_l, id LIMIT 0, 1;
+----+---------+--------+
| id | name_l  | name_f |
+----+---------+--------+
|  3 | De Niro | Robert |
+----+---------+--------+
1 row in set (0.00 sec)

SELECT * FROM personnel ORDER BY name_l, id LIMIT 1, 1;
+----+--------+--------+
| id | name_l | name_f |
+----+--------+--------+
|  5 | Duvall | Robert |
+----+--------+--------+
1 row in set (0.00 sec)

SELECT * FROM personnel ORDER BY name_l, id LIMIT 2, 1;
+----+--------+--------+
| id | name_l | name_f |
+----+--------+--------+
|  4 | Newman | Paul   |
+----+--------+--------+
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)

第一更新:(继续下面的评论)

上面的例子主要适用于你首先显示第一条记录,然后你顺序移动到下一条,也许再一步,也许一条后退,等等.你也可以轻松地向前移动x步,向后移动x步,但是这个似乎不是必需的.

但是,如果从随机记录开始,则更难以调整上述查询以获取下一个和上一个记录.

如果是这种情况,那么您可以简单地保留一个您当前所在位置的索引计数器.您首先使用$index = 0,然后显示第一条记录... LIMIT $index, 1.然后通过递增$index1 显示下一个,并通过递减$index1 显示前一个.

另一方面,如果你将渲染人员列表,然后用户将点击一个记录(随机),你也可以在应用程序端(php)的帮助下完成这项工作.假设您向用户呈现以下有序列表:

+----+-----------+--------+
| id | name_l    | name_f |
+----+-----------+--------+  // [Hidden info]
|  3 | De Niro   | Robert |  // Row 0 
|  5 | Duvall    | Robert |  // Row 1
|  4 | Newman    | Paul   |  // Row 2
|  2 | Nicholson | Jack   |  // Row 3
|  1 | Pacino    | Al     |  // Row 4
+----+-----------+--------+
Run Code Online (Sandbox Code Playgroud)

现在,如果用户点击Newman Paul,则必须将row=2参数传递给将显示该员工详细信息的页面.现在,呈现员工详细信息的页面知道Newman Paul是第3行(row=2).因此,为了得到一个和下一个记录,你会简单地改变xLIMIT x, 1row - 1前一记录,并row + 1为下:

-- Previous 
SELECT * FROM personnel ORDER BY name_l, id LIMIT 1, 1;
+----+--------+--------+
| id | name_l | name_f |
+----+--------+--------+
|  5 | Duvall | Robert |
+----+--------+--------+
1 row in set (0.00 sec)


-- Next 
SELECT * FROM personnel ORDER BY name_l, id LIMIT 3, 1;
+----+-----------+--------+
| id | name_l    | name_f |
+----+-----------+--------+
|  2 | Nicholson | Jack   |
+----+-----------+--------+
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)

第二次更新:

您可以使用以下特定于MySQL的查询来获取任何随机员工的有序列表中的记录编号,然后可以使用该编号来获取上一个和下一个记录.但请注意,这不是非常有效,如果您有数千条记录,可能会降低性能.

假设你是雇员Nicholson Jack.

您可以执行以下查询:

SELECT p.id, p.name_l, p.name_f, o.record_number
FROM   personnel p
JOIN   (
        SELECT    id,
                  @row := @row + 1 AS record_number
        FROM      personnel
        JOIN      (SELECT @row := -1) r
        ORDER BY  name_l, id
       ) o ON (o.id = p.id)
WHERE  p.name_l = 'Nicholson' AND p.name_f = 'Jack';
Run Code Online (Sandbox Code Playgroud)

哪个返回:

+----+-----------+--------+---------------+
| id | name_l    | name_f | record_number |
+----+-----------+--------+---------------+
|  2 | Nicholson | Jack   |             3 |
+----+-----------+--------+---------------+
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)

请注意,在WHERE子句中,p.id = 2如果id已知,则可以使用,而不是p.name_l = 'Nicholson' AND p.name_f = 'Jack'.

现在我们可以使用该record_number字段(3在这种情况下)来获取上一个和下一个记录,只需使用此答案顶部的原始查询,然后替换LIMIT 2, 1上一个和LIMIT 4, 1下一个.你去:

Nicholson Jack的前一个:

SELECT * FROM personnel ORDER BY name_l, id LIMIT 2, 1;
+----+--------+--------+
| id | name_l | name_f |
+----+--------+--------+
|  4 | Newman | Paul   |
+----+--------+--------+
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)

尼克尔森杰克的下一个:

SELECT * FROM personnel ORDER BY name_l, id LIMIT 4, 1;
+----+--------+--------+
| id | name_l | name_f |
+----+--------+--------+
|  1 | Pacino | Al     |
+----+--------+--------+
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)