Столкнулся недавно с задачей показа кнопок [ВПЕРЕД] [НАЗАД] на странице просмотра. Но сложность задачи в том, что сортировка может быть по произвольному полю таблицы.
Постановка задачи:
CREATE TABLE `contacts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name_prefix` varchar(50) DEFAULT NULL,
`name` varchar(100) DEFAULT NULL,
`infix` varchar(100) DEFAULT NULL,
`surname` varchar(100) NOT NULL,
`primary_email` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
Для наглядности объясню где это все работает:
есть две страницы, работающие с этой таблицей:
— index, на ней отображаются все записи из таблицы contacts, есть фильтр и есть сортировка по столбцам
— view, просмотр текущей записи из таблицы contacts. На это странице есть кнопки [ВПЕРЕД] [НАЗАД], с учетом фильтра и сортировки заданной на странице index;
Трудность возникла в этих двух кнопках.
Таким образом задача сводится к тому, чтобы получить id предыдущей и следующей записи относительно текущего id с учетом фильтра и произвольной сортировки (по любому из полей).
Если бы была сортировка по id — было бы все понятно, с фиксированной сортировкой вопрос тоже вроде бы решен http://habrahabr.ru/blogs/mysql/85945/
Для простоты и лакончиности покажу решение используя PHP.
Решение:
Ну вот собственно и все. Если у кого есть более элегантное решение WELCOME!
Постановка задачи:
CREATE TABLE `contacts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name_prefix` varchar(50) DEFAULT NULL,
`name` varchar(100) DEFAULT NULL,
`infix` varchar(100) DEFAULT NULL,
`surname` varchar(100) NOT NULL,
`primary_email` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
Для наглядности объясню где это все работает:
есть две страницы, работающие с этой таблицей:
— index, на ней отображаются все записи из таблицы contacts, есть фильтр и есть сортировка по столбцам
— view, просмотр текущей записи из таблицы contacts. На это странице есть кнопки [ВПЕРЕД] [НАЗАД], с учетом фильтра и сортировки заданной на странице index;
Трудность возникла в этих двух кнопках.
Таким образом задача сводится к тому, чтобы получить id предыдущей и следующей записи относительно текущего id с учетом фильтра и произвольной сортировки (по любому из полей).
Если бы была сортировка по id — было бы все понятно, с фиксированной сортировкой вопрос тоже вроде бы решен http://habrahabr.ru/blogs/mysql/85945/
Для простоты и лакончиности покажу решение используя PHP.
Решение:
/* Определяем условия поиска и условия сортировки.*/
$sqlConditions = " WHERE name ='test' ";
$sqlOrder = " ORDER BY name, surname";
$curId = 33; //ID текущей записи
/*Формируем основной запрос, который возвращает порядковый номер записи в отсортированном и отфильрованном наборе, и id записи*/
$sql = "SELECT rownumb,id FROM (
SELECT
@rownumb := @rownumb+1 AS rownumb,
`Contact`.`id` FROM `contacts` AS `Contact`
,(SELECT @rownumb := 0) al
$sqlConditions $sqlOrder
) AS src ";
/*Получем порядковый номер текущей записи в выборке */
$rowNumber = $this->query($sql." WHERE src.id = $curId");
/*Обрабатываем результат запроса */
if (!empty($rowNumber[0]['src']['rownumb'])) {
$rowNumber = $rowNumber[0]['src']['rownumb'];
} else{
return false;
}
if ($rowNumber > 1) {/* Если $rowNumber > 1 значит есть как минимум предыдущая запись (текущая не в начале)*/
/*Выбираем предыдущую и последующую записи относительно текущей по rownumb*/
$res = $this->query($sql." WHERE id <> $curId LIMIT ".($rowNumber - 2)." ,2");
/* Первая запись будет prevId*/
if(!empty($res[0]['src']['id'])){
$result['prevId'] = $res[0]['src']['id'];
}
/*Если вторая запись существует то она будет NextId либо текущая запись последняя в наборе*/
if(!empty($res[1]['src']['id'])){
$result['nextId'] = $res[1]['src']['id'];
}
} else { /* Если $rowNumber == 1 значит есть текущая запись стоит в начале набора данных и есть только следующая запись*/
/* Выбираем последующую запись относительно текущей*/
$res = $this->query($sql." WHERE rownumb > $rowNumber LIMIT 1");
/*Она и будет NextId*/
if(!empty($res[0]['src']['id'])){
$result['nextId'] = $res[0]['src']['id'];
}
}
* This source code was highlighted with Source Code Highlighter.
Ну вот собственно и все. Если у кого есть более элегантное решение WELCOME!