Следующая и предыдущая строка MySQL на основе имени - PullRequest
3 голосов
/ 17 июня 2010

У меня есть таблица с информацией о персонале.Я хотел бы создать следующую / предыдущую ссылку на основе фамилии этого человека.Поскольку персонал не был добавлен в алфавитном порядке, выбор следующей или предыдущей строки на основе его идентификатора не работает.

Это здоровенная таблица - соответствующие поля - id, name_l и name_f.Я хотел бы заказать по name_l фамилию отдельных лиц.

Как мне выполнить это задание?

Спасибо!

Редактировать Это будет использоваться на странице «Сведения о персонале», в результате будут сгенерированы ссылки на следующую / предыдущую запись в базе данных (упорядоченную по фамилии) на основе текущей строки.Например, если я просматриваю Джо Хаммера, ссылка «Следующая» будет ссылаться на Фрэнка Инграма.

Окончательный код

Спасибо Даниэлю, вот что я наконец-то получилработа:

Сначала я установил приращение в 0: $ i = 0 .Затем, просматривая записи с циклом , в то время как , я увеличил это значение на 1 = $ i ++ .Затем я сделал ссылку на страницу сведений для этой конкретной записи:

<a href="details.php?id=<?php echo $member['id'];?>&amp;row=<?php echo $i;?>">Details</a>

На странице сведений я использовал следующий 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'];?>&amp;row=<?php echo $nextLink;?>"><?php echo $next['name_l'] . ", " . $next['name_f'];?></a>

Ответы [ 2 ]

9 голосов
/ 17 июня 2010

Прежде всего, убедитесь, что ваш столбец 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:

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)

1-е ОБНОВЛЕНИЕ: (в дополнение к комментариям ниже)

Приведенный выше пример подходит, главным образом, если вы начинаете с отображения первой записи, а затем последовательно переходите к следующей, а может быть, снова следующей, а возможно, еще одной назад и т. Д. Вы также можете легко перемещать 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 на страницу, где будут отображаться сведения об этом сотруднике. Страница, на которой отображаются сведения о сотруднике, теперь знает, что Ньюман Пол находится в 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)

2-е ОБНОВЛЕНИЕ:

Вы можете использовать следующий специфичный для 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, если идентификатор известен, вместо 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)
0 голосов
/ 17 июня 2010

Попробуйте лучше SQL SELECT:

SELECT * FROM tblPersonnel ORDER BY name_l ASC

Попробуйте эту ссылку для получения дополнительной информации: http://w3schools.com/sql/sql_orderby.asp

...