Perl MySQL - как вернуть идентификатор последней строки таблицы, не просматривая всю таблицу?

0
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). Я действительно новичок в этом и постоянно зацикливаюсь на таких вещах.

Спасибо за любую помощь.

  • 1
    SELECT COUNT(*) from tablename даст вам количество строк, которое может или не может быть тем, что вам нужно здесь.
  • 0
    Может ли это быть так просто?
Показать ещё 2 комментария
Теги:

5 ответов

4
Лучший ответ

Попробуйте взять дополнительную строку и посмотреть, сколько строк вы действительно получили. Что-то вроде этого:

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, интерполяция чревата опасностью.

  • 0
    Спасибо, это тоже помогает.
  • 0
    Мне действительно это нравится, но я не совсем понимаю, как реализовать. Может быть, я. Пожалуйста, подтвердите. Насколько я понимаю, или его отсутствие, это возвращает has_next = 1, если есть IS другая строка вместе с выбранными данными строки, извлеченными из конца массива, или has_next = 0, если нет следующей строки и данных строки? Я учусь ???
Показать ещё 1 комментарий
3

Всегда запрашивать еще одну строку, чем вы собираетесь показывать, так как предложение 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'.

2

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-инъекциями - см. здесь для чего.)

  • 0
    Это то, что мне было нужно ... И благодаря ФИЛ и Эфиру тоже!
  • 0
    Кстати, эта схема XKCD это здорово!
Показать ещё 4 комментария
0

Хотя ваше первоначальное предложение SELECT id FROM table WHERE ... ORDER BY id DESC LIMIT 1 должно работать для поиска самого высокого идентификатора соответствия, стандартный способ сделать это: SELECT max(id) FROM table WHERE ...

  • 0
    max (id) тоже помог кучу. Вы, ребята, великолепны. Теперь я учусь использовать заполнители. Хотя это не публичный интерфейс, я считаю, что по умолчанию я должен изучить самый безопасный метод. По крайней мере, при попытке обеспечения безопасности с использованием заполнителей. Ничто не может быть «полностью» безопасным из того, что я прочитал.
0

Как указано в комментариях к Ether, для разбивки на страницы обычно требуется два запроса. Один, чтобы вернуть ваш постраничный набор, а другой - вернуть общее количество записей (используя запрос COUNT).

Зная общее количество записей, ваше текущее смещение и количество записей на каждой странице достаточное количество данных, чтобы определить, сколько страниц есть в общей сложности и сколько до и после текущей страницы.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню