Столкнулся с этой проблемой: создание навигации в php, используя данные mysql. Проблема проявилась тогда, когда я ужесточил требования от навигации, а именно: переход на страницу многостраничного списка, скажем, ответов форума, на которой находится ответ с определенным id.
Для решения нужно было:
а) определить количество страниц по N ответов на странице. Это делается легко: после запроса определяем количество записей и нехитро определяем количество страниц:
$pozstrok = ($el !== false)?mysql_num_rows($el):0;
$pages = ($pozstrok == 0)?0:ceil($pozstrok / $poskolko);
б) отыскать нужную запись, при этом пройдя до неё по предыдущим записям и наращивая счетчик. Как понимаете, если в запросе пара сот тысяч записей, а искомая находится при конце, то это ого-го какой цикл.
Оставалось или отказаться от идеи, или сильно думать.
В сильнодумающем процессе, перелопачивая тонны интернет-ресурсов, нашел ответ, как нумеровать строки с помощью пользовательских переменных mysql.
SET @t:=1;
SELECT *, @t:=@t+1 FROM baza;
Переменная получает новое значение прямо в теле запроса.
На этом основании и возникла идея: поставить метку напротив нужной записи. И если во время проставления этой метки засечь значение счетчика, то сразу получаем номер строки нужной записи. Например:
IF(baza.kod = id, @t, 0) as votono
- а потом вычислить максимум по 'votono'. В реалиях идея вылилась вот в такую формулу:
SET @t:=1, @tk=0;
SELECT @tk:= ( (@t:=@t+1)*0 + IF(baza.kod=id, @t, @tk) ), baza.* FROM baza;
после чего запрос
$el1 = mysql_query("SELECT @tk");
$r = mysql_fetch_array($el1);
возвращает номер строки нужной записи. А формула:
$page = ceil($r[0] / $poskolko) - 1;
даёт нужную страницу. Выборка страницы происходит без помощи LIMIT:
if ($pozstrok >= $page*$poskolko) @mysql_data_seek($el, $poz*$poskolko); //переходим на первую запись страницы
for ($i=0; $i < $poskolko; $i++) { //выбираем N ответов
};
В процессе поиска решения обнаружились такие проблемы:
При добавлении сортировки ORDER BY счетчик @t в некоторых запросах не давал себя прочесть, если он был оформлен как поле (@t:=@t+1 as pole1). Разместил в выражение - пока проблем не наблюдаю.
Более серьезная проблема: при добавлении выборки из другой таблицы - вообще ужас. ORDER BY срабатывал по другому, полностью нарушая работу счетчика, поэтому пришлось подворовывать поля подзапросом:
SELECT @tk:= ( (@t:=@t+1)*0 + IF(baza.kod=id, @t, @tk) ), baza.*,
(SELECT baza2.pole FROM baza2 WHERE baza.kto = baza2.kod) as pnaim
FROM baza;
Таким образом удалось выкрутиться и получить необходимый результат.
Благодаря этой метке, которая в нужное время принимает значение счетчика строк, удалось и перейти на страницу, на которой нужная запись, и подсвечивать её, т.е. внедрить поиск записи в навигацию. Мне самому понравилось.
Будь я разработчиком mysql, я бы ввел хотя бы счетчик выводимых после сортировки строк.
dnepr, 03.06.09г.