Как подсчитать количество элементов в sql-запросе?

  • 26 Ответов
  • 528 Просмотров

0 Пользователей и 1 Гость просматривают эту тему.

*

SimonovSergey

  • Осваиваюсь на форуме
  • ***
  • 56
  • 0
Подскажите пожалуйста, есть sql запрос, он выводит на странице элементы из БД, работает правильно, как подсчитать до вывода элементов их количество, чтобы цикл не делать? loadResult() выдает 1.

*

dmitry_stas

  • Профи
  • ********
  • 9665
  • 930
Код
count($rows);
?
Тут дарят бакс просто за регистрацию! Успей получить!
Все советы на форуме раздаю бесплатно, то есть даром. Индивидуально бесплатно консультирую только по вопросам стоимости индивидуальных консультаций

*

Septdir

  • Практически профи
  • *******
  • 2153
  • 108
  • JoomlaZen
Эмметтов полученных или всего (без лимитов). Если полученных то count() если всего в базе по парметрам то SQL_CALC_FOUND_ROWS + SELECT FOUND_ROWS() типа так
Код: php
 
$limitstart = 0; // Start Index
$limit = 10; // Limit
// Get Objects
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->select('SQL_CALC_FOUND_ROWS *'); // Use SQL_CALC_FOUND_ROWS
$query->from($db->quoteName('#__users'));
$db->setQuery($query, $limitstart , $limit);
$objects = $db->loadObjectList();
$total = 0;
if (!empty($objects)) {
$db->setQuery('SELECT FOUND_ROWS();');
$total = $db->loadResult();
}
Не можете справиться с задачей сами пишите, решу ее за вас, не бесплатно*.
*Интересная задача, Деньги или Бартер. Натурой не беру!
________
Мои Контакты | JoomlaZen

*

zomby6888

  • Живу я здесь
  • ******
  • 1484
  • 167
У класса JDatabase есть метод getNumRows() для таких вещей.
интернет-блог: http://websiteprog.ru

*

Septdir

  • Практически профи
  • *******
  • 2153
  • 108
  • JoomlaZen
У класса JDatabase есть метод getNumRows() для таких вещей.
Посомотрел его описание и применение. Не видел его использование с лимитом он точно работает как SQL_CALC_FOUND_ROWS
Не можете справиться с задачей сами пишите, решу ее за вас, не бесплатно*.
*Интересная задача, Деньги или Бартер. Натурой не беру!
________
Мои Контакты | JoomlaZen

*

Филипп Сорокин

  • Практически профи
  • *******
  • 1780
  • 135
А нужен вам лишний запрос? Может просто сосчитать количество элементов массива? Это куда быстрее.

Цитировать
loadResult()
Выдаёт первое попавшееся совпадение.

Вам нужен
Код
loadRowList()
или
Код
loadObjectList()
Ставь лайк, если согласен, и делай репост!

  => мои публикации
    => мои работы
      => спектр моих услуг

*

Septdir

  • Практически профи
  • *******
  • 2153
  • 108
  • JoomlaZen
А нужен вам лишний запрос? Может просто сосчитать количество элементов массива? Это куда быстрее.
А как почитаешь кол-во элементов если скажем в базе 20 элементов при лимите 10 их и в массив уйдет 10. Хотя можно и просто второй запрос.
« Последнее редактирование: 30.10.2016, 02:54:34 от Septdir »
Не можете справиться с задачей сами пишите, решу ее за вас, не бесплатно*.
*Интересная задача, Деньги или Бартер. Натурой не беру!
________
Мои Контакты | JoomlaZen

*

Филипп Сорокин

  • Практически профи
  • *******
  • 1780
  • 135
А как почитаешь кол-во элементов если скажем в базе 20 элементов при лимите 10 их и в массив уйдет 10. 
Я понятия не имею. Автор не привёл ни одного рабочего примера, также не совсем ясно, что ему нужно сделать (и нужно ли делать вообще).
Ставь лайк, если согласен, и делай репост!

  => мои публикации
    => мои работы
      => спектр моих услуг

*

Septdir

  • Практически профи
  • *******
  • 2153
  • 108
  • JoomlaZen
Вообщем проверил я  getNumRows() это просто подсчет кол-ва результатов.  Если лимит стоит 10 а строк в базе по запросу всего 20 то  выдаст 10.
Так что если нужен именно total и вы используете limit тут либо классика  = два запроса,  либо SQL_CALC_FOUND_ROWS + SELECT FOUND_ROWS() разница во та не столь большая все зависит от самого запроса ну и от кода.
Ну а если надо просто посчитать сколько эелментов пришло в массив старый добрый count($array) в помощь/
« Последнее редактирование: 30.10.2016, 03:46:54 от Septdir »
Не можете справиться с задачей сами пишите, решу ее за вас, не бесплатно*.
*Интересная задача, Деньги или Бартер. Натурой не беру!
________
Мои Контакты | JoomlaZen

*

Филипп Сорокин

  • Практически профи
  • *******
  • 1780
  • 135
Цитировать
два полных запроса
Тогда уже через join или union
Ставь лайк, если согласен, и делай репост!

  => мои публикации
    => мои работы
      => спектр моих услуг

*

Septdir

  • Практически профи
  • *******
  • 2153
  • 108
  • JoomlaZen
Тогда уже через join или union
Это простите как?
join union и подсчет сколько всего записей в базе с такими параметрами -  это кардинально разные вещи.
Еще раз повторюсь разница между   SELECT FOUND_ROWS() и двумя запросами, не такая уж и большая, так что если удобнее делать два запроса то делаешь два. К примеру если может понадобиться получать тотал отдельно или просто по коду удобнее в две функции сделать.
Да и откровенно говоря с двумя запросами куда меньше мороки с синтаксисом чем с SELECT FOUND_ROWS особенно когда идет о union
P.S У Joomla по дефолту в mvc getTotal() это второй запрос чтобы посчитать количество записей всего без limit и offset но со всеми параметрами.

P.S.S иногда лучше два запроса чем union
« Последнее редактирование: 30.10.2016, 03:38:41 от Septdir »
Не можете справиться с задачей сами пишите, решу ее за вас, не бесплатно*.
*Интересная задача, Деньги или Бартер. Натурой не беру!
________
Мои Контакты | JoomlaZen

*

zomby6888

  • Живу я здесь
  • ******
  • 1484
  • 167
Ну если нужно посчитать без учета лимитов то можно сделать подзапрос:

Код: sql
SELECT (SELECT count(*) FROM `table_name`) as count, id from `table_name` limit 1

Думаю тоже самое можно сделать и с помощью join.
интернет-блог: http://websiteprog.ru

*

Филипп Сорокин

  • Практически профи
  • *******
  • 1780
  • 135
Цитировать
Это простите как?
Миллион способов. Все зависит от задачи. А можно вообще условие заточить, при котором второго подзапроса не будет вообще. Но это автору не нужно, видимо, его и след простыл, а мы здесь копья ломаем в оффтопе, беседуя ни о чем.
Ставь лайк, если согласен, и делай репост!

  => мои публикации
    => мои работы
      => спектр моих услуг

*

SimonovSergey

  • Осваиваюсь на форуме
  • ***
  • 56
  • 0
dmitry_stas - Спасибо, то что надо  :D

*

Septdir

  • Практически профи
  • *******
  • 2153
  • 108
  • JoomlaZen
Ну если нужно посчитать без учета лимитов то можно сделать подзапрос:

Код: sql
SELECT (SELECT count(*) FROM `table_name`) as count, id from `table_name` limit 1

Думаю тоже самое можно сделать и с помощью join.
Это прокатит если нет параметров типа where и прочих иначе такой огород получится . Да и по написанию будет куда сложнее чем  SQL_CALC_FOUND_ROWS + SELECT FOUND_ROWS()
 
Миллион способов. Все зависит от задачи. А можно вообще условие заточить, при котором второго подзапроса не будет вообще. Но это автору не нужно, видимо, его и след простыл, а мы здесь копья ломаем в оффтопе, беседуя ни о чем.
Ну на форуме я такого вопроса не видел.  Хотя сама задача популярна и в сети хватает решений по вопросу как подсчитать количество строк / элементов в запросе. 
Просто вопрос тс как оказалось вообще нужно количество элементов в массиве.
Ну а на форуме такая тема полезна, хоть и не столь часто.
Не можете справиться с задачей сами пишите, решу ее за вас, не бесплатно*.
*Интересная задача, Деньги или Бартер. Натурой не беру!
________
Мои Контакты | JoomlaZen

*

dmitry_stas

  • Профи
  • ********
  • 9665
  • 930
есть мнение, что SQL_CALC_FOUND_ROWS + SELECT FOUND_ROWS() в некоторых случаях будет гораздо медленнее чем 2 последовательных запроса. но сам тесты не проводил. может кто то делал?
Тут дарят бакс просто за регистрацию! Успей получить!
Все советы на форуме раздаю бесплатно, то есть даром. Индивидуально бесплатно консультирую только по вопросам стоимости индивидуальных консультаций

*

Septdir

  • Практически профи
  • *******
  • 2153
  • 108
  • JoomlaZen
есть мнение, что SQL_CALC_FOUND_ROWS + SELECT FOUND_ROWS() в некоторых случаях будет гораздо медленнее чем 2 последовательных запроса. но сам тесты не проводил. может кто то делал?
Ну я тесты давно смотрел еще и на старом железе еще. Сейчас вроде разницы вообще нет (ну точнее она меньше минима). Так что когда надо имхо самое оно 3 функции: Параметры запроса, Обекты, Количество. Так и писать и читать удобно.
Не можете справиться с задачей сами пишите, решу ее за вас, не бесплатно*.
*Интересная задача, Деньги или Бартер. Натурой не беру!
________
Мои Контакты | JoomlaZen

*

Fedor Vlasenko

  • Профи
  • ********
  • 3800
  • 698
  • Все начинается с Value
есть мнение
неужели вы не разбираетесь в запросах, по вышеприведенной  ссылке сравниваются совсем разные запросы, с разными параметрами и соответственно, результатами на выходе
простите, но это откровенно чушь. Лишь бы, что-то написать

*

zomby6888

  • Живу я здесь
  • ******
  • 1484
  • 167
Автор  просто пишет что разница зависит от наличия индексов в where/order. Если индексы присутствуют то два запроса будут быстрее (причем ощутимо), если нет то медленнее. Не вижу ничего зазорного чтобы выполнить два запроса. Экономия на спичках получается. Запрос с count возможно будет более универсальным так как поддерживается не только MySQL движками.  
« Последнее редактирование: 30.10.2016, 18:31:07 от zomby6888 »
интернет-блог: http://websiteprog.ru

*

Fedor Vlasenko

  • Профи
  • ********
  • 3800
  • 698
  • Все начинается с Value
Автор  просто пишет что разница зависит от наличия индексов
Я скажу так, если вы пишите приложения ине пропускаете запросы через Explain, то откровенно вы ***кодите.
Наличие идексов еще не говорит что База выберет план с использованием этих индексов. Потому Explain обязателен.
Между двумя запросами и одним есть разница и всегда будет. Остальное от не знаний как совместить два запроса.
А разница здесь в времени передачи запроса на сервер и прием данных на сервер. То время которое вам никак не покажет анализатор запроса.
Я не утверждаю, что один запрос лучше, а только указываю на факторы которые мы почему-то пропускаем сравнивая запросы.

*

dmitry_stas

  • Профи
  • ********
  • 9665
  • 930
простите, но это откровенно чушь. Лишь бы, что-то написать
Федор, вы можете не просить прощения, я на вас никогда не обижаюсь :)

в этой статье да, действительно разные. но есть другие, в которых сравнивается одно и тоже. не обращал на это внимания, просто взял первую попавшуюся в качестве примера. смысл не в том, что выбираются разные данные, а в том, что в статье описан EXPLAIN который при SQL_CALC_FOUND_ROWS показывает, что MySQL делает физическую выборку всех строк, а не только инкрементирует счетчик, как в случае с COUNT, несмотря на LIMIT 5. и я проверил только что, это действительно так. вот результаты 3 запросов:

выборка 5 строк: http://prnt.sc/d0tjfd
выборка COUNT: http://prnt.sc/d0tish
выборка 5 строк с SQL_CALC_FOUND_ROWS : http://prnt.sc/d0tj8k

на таблице из 2194 строк первые 2 запроса по сумме дали 0,0023 секунды, в то время как третий дал 0,0135 секунды. выводы я думаю очевидны

P.S. подумал, что надо наверное еще один скрин показать - http://prntscr.com/d0tofr . т.е. неважно, есть ли индекс для поля, по которому сортируем. важно другое, SQL_CALC_FOUND_ROWS заставляет MySQL выстраивать по этому полю всю таблицу, а не только ту часть, которая попадает под WHERE
« Последнее редактирование: 30.10.2016, 19:02:00 от dmitry_stas »
Тут дарят бакс просто за регистрацию! Успей получить!
Все советы на форуме раздаю бесплатно, то есть даром. Индивидуально бесплатно консультирую только по вопросам стоимости индивидуальных консультаций

*

zomby6888

  • Живу я здесь
  • ******
  • 1484
  • 167
По моему эта функция просто не использует индексы. Вообще. Отсюда такой результат.
интернет-блог: http://websiteprog.ru

*

Fedor Vlasenko

  • Профи
  • ********
  • 3800
  • 698
  • Все начинается с Value
простите, но это откровенно чушь. Лишь бы, что-то написать
Данные строки адресованы к автору статьи. Как то
Цитировать
принято
, что на английском это чуть ли не первоисточник
И читает же каждый как-то по своему.
А ТС вы правильно ответили есть count

*

dmitry_stas

  • Профи
  • ********
  • 9665
  • 930
По моему эта функция просто не использует индексы. Вообще. Отсюда такой результат.
использует, дело в другом. просто с SQL_CALC_FOUND_ROWS результат такой же, как если бы запрос был
Цитировать
SELECT COUNT(*) FROM ... ORDER BY ...
такой count тоже будет долгим, потому что это заставит MySQL сначала выбрать все сроки, отсортировать их по полю, а только потом посчитать. и с SQL_CALC_FOUND_ROWS получается тоже самое - несмотря на явно заданный WHERE выбираются и сортируются все равно все строки, а не только попадающие под условие. потому что строки то все посчитать надо. вот и получается, что он сначала сортирует, считает, а только потом отбирает WHERE.

Данные строки адресованы к автору статьи
тогда видимо моя очередь извиняться  *DRINK*
Тут дарят бакс просто за регистрацию! Успей получить!
Все советы на форуме раздаю бесплатно, то есть даром. Индивидуально бесплатно консультирую только по вопросам стоимости индивидуальных консультаций

*

Septdir

  • Практически профи
  • *******
  • 2153
  • 108
  • JoomlaZen
использует, дело в другом. просто с SQL_CALC_FOUND_ROWS результат такой же, как если бы запрос был
Нет она быстрее. на мизер но быстрее.
Не можете справиться с задачей сами пишите, решу ее за вас, не бесплатно*.
*Интересная задача, Деньги или Бартер. Натурой не беру!
________
Мои Контакты | JoomlaZen

*

dmitry_stas

  • Профи
  • ********
  • 9665
  • 930
Нет она быстрее.
ну не спорю, но я в тестах получал плюс минус одно и тоже по времени, просто погрешность.

P.S. кстати имхо такое поведение SQL_CALC_FOUND_ROWS - явная недоработка оптимизации MySQL. теряется весь смысл этого. она не должна делать сортировку до where, должна просто посчитать строки по where, а потом уже сортировать только отобранные.

P.P.S. проверил ради интереса на MariaDB - результат такой же.
« Последнее редактирование: 30.10.2016, 19:49:09 от dmitry_stas »
Тут дарят бакс просто за регистрацию! Успей получить!
Все советы на форуме раздаю бесплатно, то есть даром. Индивидуально бесплатно консультирую только по вопросам стоимости индивидуальных консультаций

*

Septdir

  • Практически профи
  • *******
  • 2153
  • 108
  • JoomlaZen
Ну если мечтать  то было не плохо получать тотал всегда. Без бубнов доп запросов под запросов и максимально быстро и оптимизированно.
Не можете справиться с задачей сами пишите, решу ее за вас, не бесплатно*.
*Интересная задача, Деньги или Бартер. Натурой не беру!
________
Мои Контакты | JoomlaZen