我有一张包含人员详细信息的表格。我想根据个人的姓氏创建一个Next / Previous链接。由于人员未按字母顺序添加,因此根据其ID选择下一行或上一行不起作用。
这是一个很大的表 - 相关的字段是id,name_l和name_f。我想通过name_l订购个人的姓氏。
我将如何完成这项任务?
谢谢!
修改 这将在Personnel Details页面上使用,结果将生成基于当前行的数据库中下一个/ prev条目的链接(按姓氏排序)。例如,如果我正在查看Joe Hammer,则Next链接将链接到Frank Ingram。
最终代码
感谢Daniel,以下是我最终的工作:
首先,我将增量设置为0: $ i = 0 。然后,在循环使用 while 循环的记录时,我将其增加1 = $ i ++ 。然后我链接到该特定条目的详细信息页面:
<a href="details.php?id=<?php echo $member['id'];?>&row=<?php echo $i;?>">Details</a>
在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;
最后,链接:
<a href="member_details.php?id=<?php echo $next['id'];?>&row=<?php echo $nextLink;?>"><?php echo $next['name_l'] . ", " . $next['name_f'];?></a>
答案 0 :(得分:9)
首先,确保您的name_l
列已编入索引。然后,您只需使用ORDER BY
和LIMIT
子句,如下所示:
SELECT * FROM personnel ORDER BY name_l, id LIMIT 0, 1;
只需递增LIMIT
子句中的0值即可选择有序集合中的下一条记录。因此,使用LIMIT 1, 1
获取第二条记录,使用LIMIT 2, 1
获取第三条记录
要在name_l
上创建索引,您可以使用CREATE INDEX
命令:
CREATE INDEX ix_index_name ON personnel (name_l);
测试用例:
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');
结果:
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)
第一次更新:(继续下面的评论)
上面的示例主要适用于您首先显示第一条记录,然后依次移动到下一条记录,也可能再次下一步,也许后退一条等等。您还可以轻松向前移动x步,向后移动x步,但这似乎不是必需的。
但是,如果从随机记录开始,则更难以调整上述查询以获取下一个和以前的记录。
如果是这种情况,那么您可以简单地保留一个您当前所在位置的索引计数器。您从$index = 0
开始,并使用... LIMIT $index, 1
显示第一条记录。然后通过将$index
递增1来显示下一个,并通过将$index
递减1来显示上一个。
如果另一方面,你将渲染人员列表,然后用户将点击一个记录(随机),你也可以在应用程序端(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
+----+-----------+--------+
现在,如果用户点击Newman Paul,您必须将row=2
参数传递给将显示该员工详细信息的页面。现在,呈现员工详细信息的页面知道Newman Paul是第3行(row=2
)。因此,要获取上一个和下一个记录,您只需将x
中的LIMIT x, 1
更改为row - 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)
第二次更新:
您可以使用以下特定于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';
返回此内容:
+----+-----------+--------+---------------+
| id | name_l | name_f | record_number |
+----+-----------+--------+---------------+
| 2 | Nicholson | Jack | 3 |
+----+-----------+--------+---------------+
1 row in set (0.00 sec)
请注意,在WHERE
子句中,如果ID已知,则可以使用p.id = 2
,而不是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)
Nicholson Jack的下一个:
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)
答案 1 :(得分:0)
尝试更好的SQL SELECT语句:
SELECT * FROM tblPersonnel ORDER BY name_l ASC
试试此链接了解更多信息: http://w3schools.com/sql/sql_orderby.asp