my $sth = $dbh->prepare("SELECT id
FROM user
WHERE group == '1'
ORDER BY id DESC
LIMIT 1");
Я пытался получить идентификатор последней строки в таблице, не читая всю таблицу.
Я уже обращаюсь через:
my $sth = $dbh->prepare("SELECT name,
group
FROM user
WHERE group == '1'
LIMIT $from, $thismany");
$sth->execute();
while(my ($name,$group) = $sth->fetchrow_array()) {
... и создайте небольшой запрос на разбивку по страницам, как вы можете видеть.
Но я пытаюсь выяснить, как определить, когда я нахожусь в последних (< = 500) строках, чтобы отключить ссылку "следующий 500". Все остальное работает нормально. Я выяснил, как отключить ссылку "предыдущий 500", когда на первой странице 500 все я сам!
Я думал, что настрою "переключатель" в цикле while, поэтому, если ($ id = $last_id), я могу установить "switch" var.
Как
if ($id = $last_id) {
$lastpage = 1; #the switch
}
Поэтому я могу отключить следующую 500 ссылок, если ($ lastpage == 1). Я действительно новичок в этом и постоянно зацикливаюсь на таких вещах.
Спасибо за любую помощь.
Попробуйте взять дополнительную строку и посмотреть, сколько строк вы действительно получили. Что-то вроде этого:
my @results = ( );
my $total = 0;
my $sth = $dbh->prepare(qq{
SELECT name, group
FROM user
WHERE group = ?
LIMIT ?, ?
});
$sth->execute(1, $from, $thismany + 1);
while(my ($name, $group) = $sth->fetchrow_array()) {
push(@results, [$name, $group]); # Or something more interesting.
++$total;
}
$sth->finish();
my $has_next = 0;
if($total == $thismany + 1) {
pop(@results);
$has_next = 1;
}
И BTW, пожалуйста, используйте заполнители в все вашего SQL, интерполяция чревата опасностью.
Всегда запрашивать еще одну строку, чем вы собираетесь показывать, так как предложение mu слишком короткое, это хороший способ.
Но если вы хотите использовать другой предложенный подход для выполнения двух отдельных запросов, один для получения нужных строк и один для получения общего счета, если не было предложения ограничения, MySQL обеспечивает простой способ сделать это объединяя как можно большую часть работы:
SELECT SQL_CALC_FOUND_ROWS name, group FROM user WHERE group = '1' LIMIT ..., ...;
то
SELECT FOUND_ROWS();
Отметчик SQL_CALC_FOUND_ROWS изменяет то, что возвращает следующий FOUND_ROWS(), не требуя от вас выполнения всего отдельного запроса SELECT COUNT(*) from user WHERE group = '1'
.
SELECT COUNT(*) from tablename
даст вам количество строк, поэтому, если вы сохраните количество запусков, сколько строк вы прочитали до сих пор, вы узнаете, когда находитесь на последней странице результатов.
Вы можете сгенерировать этот запрос с помощью (untested, от хорошей рабочей станции в настоящий момент):
my $sth = $dbh->prepare("select COUNT(*) FROM user WHERE group == '1'");
my @data = $sth->fetchrow_array;
my $count = $data->[0];
(PS. вы должны знать о проблемах с SQL-инъекциями - см. здесь для чего.)
Хотя ваше первоначальное предложение SELECT id FROM table WHERE ... ORDER BY id DESC LIMIT 1
должно работать для поиска самого высокого идентификатора соответствия, стандартный способ сделать это: SELECT max(id) FROM table WHERE ...
Как указано в комментариях к Ether, для разбивки на страницы обычно требуется два запроса. Один, чтобы вернуть ваш постраничный набор, а другой - вернуть общее количество записей (используя запрос COUNT).
Зная общее количество записей, ваше текущее смещение и количество записей на каждой странице достаточное количество данных, чтобы определить, сколько страниц есть в общей сложности и сколько до и после текущей страницы.
SELECT COUNT(*) from tablename
даст вам количество строк, которое может или не может быть тем, что вам нужно здесь.