首先,请确保您的name_l
列已建立索引。然后你可以简单地使用ORDER BY
和LIMIT
条款如下:
SELECT * FROM personnel ORDER BY name_l, id LIMIT 0, 1;
只需增加 0 值即可LIMIT
子句来选择有序集中的下一条记录。因此使用LIMIT 1, 1
获得第二条记录,LIMIT 2, 1
对于第三个,等等。
创建索引name_l
你可以使用CREATE INDEX http://dev.mysql.com/doc/refman/5.1/en/create-index.html命令:
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');
Results:
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
by 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 是第三行 (row=2
)。因此,要获取上一条和下一条记录,您只需更改x
in LIMIT x, 1
by 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 的查询来获取任意随机员工的有序列表中的记录编号,然后可以使用该记录编号来获取上一条记录和下一条记录。但请注意,这不是很有效,如果您有数千条记录,则可能会降低性能。
假设您是员工尼克尔森·杰克。
您可以执行以下查询:
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
你可以使用的条款p.id = 2
如果 id 已知,则代替p.name_l = 'Nicholson' AND p.name_f = 'Jack'
.
现在我们可以使用record_number
场,即3
在这种情况下,要获取上一条和下一条记录,只需使用此答案顶部的原始查询,然后替换LIMIT 2, 1
对于之前的和LIMIT 4, 1
对于下一个。就这样:
尼克尔森·杰克的前身:
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)
尼科尔森·杰克的下一个:
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)