Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В. PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Вывод последних n записей
 
 автор: Евгений Петров   (27.06.2005 в 15:35)   письмо автору
 
 

Как можно вывести из таблицы последние N записей.
P.S. В таблице есть поле ID auto_increment.

   
 
 автор: P@Sol   (27.06.2005 в 15:48)   письмо автору
 
   для: Евгений Петров   (27.06.2005 в 15:35)
 


select name from book limit 2,3


Выбрать имена из таблицы book и отобразить 3 строки, начиная со второй;)

   
 
 автор: Евгений Петров   (27.06.2005 в 16:20)   письмо автору
 
   для: P@Sol   (27.06.2005 в 15:48)
 

Мне не надо с какой то по какую то, мне надо с {последняя-N} до {последняя}

   
 
 автор: P@Sol   (27.06.2005 в 16:32)   письмо автору
 
   для: Евгений Петров   (27.06.2005 в 16:20)
 



$result = mysql_querry(select avtor from book);
$num = mysql_num_rows($result); //сколько всего записей
$k=10; //сколько надо вывести
$result = mysql_querry(select avtor from book limit $num-$k,$k);

   
 
 автор: Loki   (27.06.2005 в 16:48)   письмо автору
 
   для: P@Sol   (27.06.2005 в 16:32)
 

только

$result = mysql_querry(select avtor from book limit $num-$k-1,$k); 

Так как нумерация строк начинается с нуля, а количество записей получается номер+1

   
 
 автор: Loki   (27.06.2005 в 16:22)   письмо автору
 
   для: Евгений Петров   (27.06.2005 в 15:35)
 

Тогда скорее так:

SELECT * FROM table ORDER BY id DESC LIMIT N

Правда, при этому они будут отсортированы в обратном порядке, а иначе, вроде как, только двумя запросами.

   
 
 автор: Евгений Петров   (29.06.2005 в 01:30)   письмо автору
 
   для: Loki   (27.06.2005 в 16:22)
 

Помоему в этом случае выберутся ПЕРВЫЕ N записей, только отсортированные в обратном порядке.

   
 
 автор: Loki   (29.06.2005 в 09:54)   письмо автору
 
   для: Евгений Петров   (29.06.2005 в 01:30)
 

Да нет. Данные сначала сортируются, а потом выбираются - уже неоднократно наступал на эти грабли. Да вы сами проверьте;)

   
 
 автор: Евгений Петров   (29.06.2005 в 11:36)   письмо автору
 
   для: Loki   (29.06.2005 в 09:54)
 

И правда, а почему так происходит? Это ж сколько он будет выбирать из базы с, например, 10 000 000 записей.
ЗЫ: А можно это как то отсортировать в правильном порядке? :)

   
 
 автор: P@Sol   (29.06.2005 в 11:47)   письмо автору
 
   для: Евгений Петров   (29.06.2005 в 11:36)
 

занеси их в массив и так их sort()...а чем мой способ не устраивает?

   
 
 автор: Евгений Петров   (29.06.2005 в 11:53)   письмо автору
 
   для: P@Sol   (29.06.2005 в 11:47)
 

>>а чем мой способ не устраивает?
Зачем два раза гонять БД, если можно это за один раз сделать, а то что они в обратном порядке в принципе не беда можно просто потом в обратном порядке записывать (правда придумать бы ещё как :))) )

   
 
 автор: P@Sol   (29.06.2005 в 12:01)   письмо автору
 
   для: Евгений Петров   (29.06.2005 в 11:53)
 

занеси их в массив и там их sort()...

p.s. все равно рано или поздно понадобится общее кол-во записей;)

   
 
 автор: Евгений Петров   (29.06.2005 в 12:04)   письмо автору
 
   для: P@Sol   (29.06.2005 в 12:01)
 

Опять же это лишнее действие, зачем сортировать уже отсортированные данные?

   
 
 автор: Евгений Петров   (29.06.2005 в 12:02)   письмо автору
 
   для: Евгений Петров   (29.06.2005 в 11:53)
 

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

$result = mysql_querry(select avtor from book);

кстати я бы его заменил так:

$result = mysql_querry(select count(*) from book);

а как нибудь по другому. Как я уже и говорил в таблице есть поле id auto_increment, можно смотреть по последнему ключу, но может возникнуть проблема если некоторые записи будут удаляться. В любом случае спасибо за помощь.

   
 
 автор: P@Sol   (29.06.2005 в 12:09)   письмо автору
 
   для: Евгений Петров   (29.06.2005 в 12:02)
 

>кстати я бы его заменил так:

>$result = mysql_querry(select count(*) from book);
>

все равно два запроса:)

   
 
 автор: Евгений Петров   (29.06.2005 в 12:12)   письмо автору
 
   для: P@Sol   (29.06.2005 в 12:09)
 

Запроса то два, но в первом случае из БД выбираются записи и заносятся в массив (а это лишняя память), а во втором только подсчитывается количество записей.

   
 
 автор: cheops   (29.06.2005 в 12:25)   письмо автору
 
   для: Евгений Петров   (29.06.2005 в 12:12)
 

На самом деле если тип таблицы MyISAM, то полного сканирования таблицы при запросе
$result = mysql_query("select count(*) from book");

не происходит - возвращается значение счётчика, который хранится в таблице. Т.е. этот запрос осуществляется очень быстро.

   
 
 автор: Евгений Петров   (29.06.2005 в 12:28)   письмо автору
 
   для: cheops   (29.06.2005 в 12:25)
 

Тогда всё OK! Cпасибо!

   
 
 автор: Евгений Петров   (29.06.2005 в 13:56)   письмо автору
 
   для: Евгений Петров   (29.06.2005 в 12:28)
 

Возникла проблемка! Теперь задачка на соображалку звучит так: "Вы брать послдение N записей В КОТОРЫХ ВЫПОЛНЯЕТСЯ УСЛОВИЕ X". Есть предложения?

   
 
 автор: P@Sol   (29.06.2005 в 14:00)   письмо автору
 
   для: Евгений Петров   (29.06.2005 в 13:56)
 

<?
if ($k=10)
{
   
$resul =...
 
//и другие дела
}
else echo 
"Условие не выполнено";

   
 
 автор: Евгений Петров   (29.06.2005 в 14:59)   письмо автору
 
   для: P@Sol   (29.06.2005 в 14:00)
 

Нет, надо, например, из тысячи записей выбрать последние 20 (именно 20), которые удовлетворяют условию. Т.е. в принципе выборка может начаться и не с {количество записей}-N записи, а раньше, но в итоге должен бвть массив из 20 элементов.

   
 
 автор: Loki   (29.06.2005 в 14:17)   письмо автору
 
   для: Евгений Петров   (29.06.2005 в 13:56)
 

А по-моему речь об этом:

SELECT * FROM table WHERE X ORDER BY id DESC LIMIT N

   
 
 автор: P@Sol   (29.06.2005 в 14:27)   письмо автору
 
   для: Loki   (29.06.2005 в 14:17)
 

;) я не внимательно прочел...:(

   
 
 автор: Евгений Петров   (29.06.2005 в 15:02)   письмо автору
 
   для: Loki   (29.06.2005 в 14:17)
 

Я точно не уверен, но помоему в этом случае если не выполнится какое нибудь условие то записей будет меньше нужного.

   
 
 автор: P@Sol   (29.06.2005 в 15:13)   письмо автору
 
   для: Евгений Петров   (29.06.2005 в 15:02)
 

тогда тебе точно надо делать так:)
<?
$result 
mysql_querry(select count(*) from book where avtor like "Антон %"); 
$num mysql_result($result,0); //сколько всего записей 
$k=10//сколько надо вывести 
$if ($num>$k$k=10//если записей больше, чем надо вывести, то выводим 10
else $k=$num//если меньше, то выводим все
$result mysql_querry(select avtor from book limit $num-$k,$k); 

   
 
 автор: Евгений Петров   (29.06.2005 в 15:44)   письмо автору
 
   для: P@Sol   (29.06.2005 в 15:13)
 

И что все равно получается тоже самое. Второй параметр аттрибута limit задает МАКСИМАЛЬНОЕ количесвто выбираемых записей. Т.е. опять же если не выполняется какое нибудь условие то выбранных записей будет меньше.

   
 
 автор: P@Sol   (29.06.2005 в 15:58)   письмо автору
 
   для: Евгений Петров   (29.06.2005 в 15:44)
 

не понял....например?

тот код делает следующее..в таблице avtor ищет все что похоже на Антон...допустим он нашел 9...
9<10 => выводиться 9 записей, а если бы нашел 11, то вывел бы 10 записей

а если запись не соответствует условию зачем ее выводить??

   
 
 автор: Евгений Петров   (29.06.2005 в 16:06)   письмо автору
 
   для: P@Sol   (29.06.2005 в 15:58)
 

Ну во превых здесь уже два запроса, а во вторых он то выведет 10 или 9 записей, но это будут 9 последних записей. Я постараю сь наглядно это отбразить. Например нужно выбрать последние 5 запсией в которых есть "0":

Что мне нужно?     
1111111111       
1111011111
1111111110       
1111110111
1111101111
1111111111       
1111111111       
1111110111
1111111111       
1111111011
1111111111
       
Что получится у тебя?
1111111111       
1111011111
1111111110       
1111110111
1111101111
1111111111       
1111111111       
1111110111
1111111111       
1111111011
1111111111       

Видишь разницу?

   
 
 автор: P@Sol   (29.06.2005 в 16:13)   письмо автору
 
   для: Евгений Петров   (29.06.2005 в 16:06)
 

$result = mysql_querry(select avtor from book where avtor like "%0%"); 
  $num_result = mysql_num_rows($result); 
 if ($num_result > $k) $k=10;
 else $k = $num_result;

  for ($i=0; $i < $k; $i++) 
  { 
          $row = mysql_fetch_array($result); 
          $name[$i] = $row["name"]; 
   } 

   
 
 автор: Евгений Петров   (29.06.2005 в 16:18)   письмо автору
 
   для: P@Sol   (29.06.2005 в 16:13)
 

Так точно считает что строк 5 и выводит последние 5 записей. Я не прав?

   
 
 автор: Евгений Петров   (29.06.2005 в 16:20)   письмо автору
 
   для: P@Sol   (29.06.2005 в 16:13)
 

А вэтом случае выведет все записи где есть 0

   
 
 автор: P@Sol   (29.06.2005 в 16:31)   письмо автору
 
   для: P@Sol   (29.06.2005 в 16:13)
 

может так?
<?
$result 
mysql_querry(select from book where
avtor like 
"%0%"); 
  
$num_result mysql_num_rows($result); // допусти 16
 
if ($num_result $k$k=20;
 else 
$k $num_result//$k=16

  
for ($i=0$i $k$i++) 
  { 
          
$row mysql_fetch_array($result); 
          
$name[$i] = $row["name"];  // заносим все записи в $name 
   


а выводить так
<?
for ($i=count($name)-$k$i<count($name);$i++)  //выводим с 0 по 15
echo $name[$i];

   
 
 автор: Евгений Петров   (29.06.2005 в 16:35)   письмо автору
 
   для: P@Sol   (29.06.2005 в 16:31)
 

Не, не то.

   
 
 автор: P@Sol   (29.06.2005 в 16:44)   письмо автору
 
   для: P@Sol   (29.06.2005 в 16:31)
 

>может так?
<?
$result 
mysql_querry(select from book where
avtor like 
"%0%"); 
  
$num_result mysql_num_rows($result); // допусти 16

  
for ($i=0$i $num_result$i++) 
  { 
          
$row mysql_fetch_array($result); 
          
$name[$i] = $row["name"];  // заносим все записи в $name 
   


а выводить так
<?
 $k
=10//надо 10 записей
 
if ($num_result $k$k=10;
 else 
$k $num_result
//$k = 10
for ($i=count($name)-$k$i<count($name)-1;$i++)  //выводим с 16-10  по 15
echo $name[$i];

   
 
 автор: Loki   (29.06.2005 в 16:43)   письмо автору
 
   для: Евгений Петров   (29.06.2005 в 16:06)
 

Евгений, мой запрос, который я привел в самом верху, как раз и выведет то, что вам нужно:
sql сначала обрабатывает where, затем order, затем limit... Собственно, создайте тестовую базу, да попробуйте.

   
 
 автор: Евгений Петров   (29.06.2005 в 17:26)   письмо автору
 
   для: Loki   (29.06.2005 в 16:43)
 

Да запрос действительно выведет то что мне надо, но есть 2 НО:
1) данные выводятся в обратном порядке (впринципе терпимо)
2) меня мучает вопрос об оптимальности. Ведь насколько я понял вся таблица сортируется, а потом извлекаются записи. И тут же ещё один вопрос: не нарушится ли последовательность расположения записей в таблице после сортировки?

   
 
 автор: Loki   (29.06.2005 в 17:52)   письмо автору
 
   для: Евгений Петров   (29.06.2005 в 17:26)
 

1. об этом я предупреждал с самого начала
2. Таблица не сортируются физически, кроме того, сортируете вы ее по индексному полю, что должно быть достаточно быстро (если я ничего не путаю), а в третьих сортируется не вся таблица, а только ваши N записей (см. пост выше).

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования