Форум русской поддержки Joomla!® CMS
09.12.2016, 07:57:49 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
   
   Начало   Поиск Joomla 3.0 FAQ Joomla 2.5 FAQ Joomla 1.5 FAQ Правила форума Новости Joomla Реклама Войти Регистрация Помощь  
Страниц: [1]   Вниз
  Добавить закладку  |  Печать  
Автор

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

 (Прочитано 272 раз)
0 Пользователей и 1 Гость смотрят эту тему.
SimonovSergey
Осваиваюсь на форуме
***

Репутация: +0/-0
Offline Offline

Сообщений: 51


« : 29.10.2016, 19:29:12 »

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

Репутация: +798/-4
Offline Offline

Сообщений: 7776



« Ответ #1 : 29.10.2016, 19:49:49 »

Код:
count($rows);
?
Записан
Septdir
Живу я здесь
******

Репутация: +36/-3
Offline Offline

Пол: Мужской
Сообщений: 841


Skype: septdir


« Ответ #2 : 29.10.2016, 21:36:12 »

Эмметтов полученных или всего (без лимитов). Если полученных то count() если всего в базе по парметрам то SQL_CALC_FOUND_ROWS + SELECT FOUND_ROWS() типа так
Код
 
$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();
}
 
Записан
zomby6888
Живу я здесь
******

Репутация: +168/-3
Offline Offline

Пол: Мужской
Сообщений: 1538


« Ответ #3 : 29.10.2016, 23:07:51 »

У класса JDatabase есть метод getNumRows() для таких вещей.
Записан
Septdir
Живу я здесь
******

Репутация: +36/-3
Offline Offline

Пол: Мужской
Сообщений: 841


Skype: septdir


« Ответ #4 : 30.10.2016, 01:42:47 »

У класса JDatabase есть метод getNumRows() для таких вещей.
Посомотрел его описание и применение. Не видел его использование с лимитом он точно работает как SQL_CALC_FOUND_ROWS
Записан
Филипп Сорокин
Живу я здесь
******

Репутация: +121/-4
Offline Offline

Пол: Мужской
Сообщений: 1466


« Ответ #5 : 30.10.2016, 01:47:05 »

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

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

Вам нужен
Код:
loadRowList()
или
Код:
loadObjectList()
Записан
Septdir
Живу я здесь
******

Репутация: +36/-3
Offline Offline

Пол: Мужской
Сообщений: 841


Skype: septdir


« Ответ #6 : 30.10.2016, 01:51:29 »

А нужен вам лишний запрос? Может просто сосчитать количество элементов массива? Это куда быстрее.
А как почитаешь кол-во элементов если скажем в базе 20 элементов при лимите 10 их и в массив уйдет 10. Хотя можно и просто второй запрос.
« Последнее редактирование: 30.10.2016, 01:54:34 от Septdir » Записан
Филипп Сорокин
Живу я здесь
******

Репутация: +121/-4
Offline Offline

Пол: Мужской
Сообщений: 1466


« Ответ #7 : 30.10.2016, 01:53:15 »

А как почитаешь кол-во элементов если скажем в базе 20 элементов при лимите 10 их и в массив уйдет 10. 
Я понятия не имею. Автор не привёл ни одного рабочего примера, также не совсем ясно, что ему нужно сделать (и нужно ли делать вообще).
Записан
Septdir
Живу я здесь
******

Репутация: +36/-3
Offline Offline

Пол: Мужской
Сообщений: 841


Skype: septdir


« Ответ #8 : 30.10.2016, 02:12:16 »

Вообщем проверил я  getNumRows() это просто подсчет кол-ва результатов.  Если лимит стоит 10 а строк в базе по запросу всего 20 то  выдаст 10.
Так что если нужен именно total и вы используете limit тут либо классика  = два запроса,  либо SQL_CALC_FOUND_ROWS + SELECT FOUND_ROWS() разница во та не столь большая все зависит от самого запроса ну и от кода.
Ну а если надо просто посчитать сколько эелментов пришло в массив старый добрый count($array) в помощь/
« Последнее редактирование: 30.10.2016, 02:46:54 от Septdir » Записан
Филипп Сорокин
Живу я здесь
******

Репутация: +121/-4
Offline Offline

Пол: Мужской
Сообщений: 1466


« Ответ #9 : 30.10.2016, 02:15:43 »

Цитировать
два полных запроса
Тогда уже через join или union
Записан
Septdir
Живу я здесь
******

Репутация: +36/-3
Offline Offline

Пол: Мужской
Сообщений: 841


Skype: septdir


« Ответ #10 : 30.10.2016, 02:24:18 »

Тогда уже через 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, 02:38:41 от Septdir » Записан
zomby6888
Живу я здесь
******

Репутация: +168/-3
Offline Offline

Пол: Мужской
Сообщений: 1538


« Ответ #11 : 30.10.2016, 03:12:12 »

Ну если нужно посчитать без учета лимитов то можно сделать подзапрос:

Код
SELECT (SELECT count(*) FROM `table_name`) AS count, id FROM `table_name` LIMIT 1
 

Думаю тоже самое можно сделать и с помощью join.
Записан
Филипп Сорокин
Живу я здесь
******

Репутация: +121/-4
Offline Offline

Пол: Мужской
Сообщений: 1466


« Ответ #12 : 30.10.2016, 04:08:05 »

Цитировать
Это простите как?
Миллион способов. Все зависит от задачи. А можно вообще условие заточить, при котором второго подзапроса не будет вообще. Но это автору не нужно, видимо, его и след простыл, а мы здесь копья ломаем в оффтопе, беседуя ни о чем.
Записан
SimonovSergey
Осваиваюсь на форуме
***

Репутация: +0/-0
Offline Offline

Сообщений: 51


« Ответ #13 : 30.10.2016, 11:11:19 »

dmitry_stas - Спасибо, то что надо  Cheesy
Записан
Septdir
Живу я здесь
******

Репутация: +36/-3
Offline Offline

Пол: Мужской
Сообщений: 841


Skype: septdir


« Ответ #14 : 30.10.2016, 11:56:03 »

Ну если нужно посчитать без учета лимитов то можно сделать подзапрос:

Код
SELECT (SELECT count(*) FROM `table_name`) AS count, id FROM `table_name` LIMIT 1
 

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

Репутация: +798/-4
Offline Offline

Сообщений: 7776



« Ответ #15 : 30.10.2016, 14:17:59 »

есть мнение, что SQL_CALC_FOUND_ROWS + SELECT FOUND_ROWS() в некоторых случаях будет гораздо медленнее чем 2 последовательных запроса. но сам тесты не проводил. может кто то делал?
Записан
Septdir
Живу я здесь
******

Репутация: +36/-3
Offline Offline

Пол: Мужской
Сообщений: 841


Skype: septdir


« Ответ #16 : 30.10.2016, 16:02:52 »

есть мнение, что SQL_CALC_FOUND_ROWS + SELECT FOUND_ROWS() в некоторых случаях будет гораздо медленнее чем 2 последовательных запроса. но сам тесты не проводил. может кто то делал?
Ну я тесты давно смотрел еще и на старом железе еще. Сейчас вроде разницы вообще нет (ну точнее она меньше минима). Так что когда надо имхо самое оно 3 функции: Параметры запроса, Обекты, Количество. Так и писать и читать удобно.
Записан
Fedor Vlasenko
Профи
********

Репутация: +696/-5
Offline Offline

Пол: Мужской
Сообщений: 3820


Все начинается с Value


« Ответ #17 : 30.10.2016, 17:06:54 »

есть мнение
неужели вы не разбираетесь в запросах, по вышеприведенной  ссылке сравниваются совсем разные запросы, с разными параметрами и соответственно, результатами на выходе
простите, но это откровенно чушь. Лишь бы, что-то написать
Записан
zomby6888
Живу я здесь
******

Репутация: +168/-3
Offline Offline

Пол: Мужской
Сообщений: 1538


« Ответ #18 : 30.10.2016, 17:25:16 »

Автор  просто пишет что разница зависит от наличия индексов в where/order. Если индексы присутствуют то два запроса будут быстрее (причем ощутимо), если нет то медленнее. Не вижу ничего зазорного чтобы выполнить два запроса. Экономия на спичках получается. Запрос с count возможно будет более универсальным так как поддерживается не только MySQL движками.  
« Последнее редактирование: 30.10.2016, 17:31:07 от zomby6888 » Записан
Fedor Vlasenko
Профи
********

Репутация: +696/-5
Offline Offline

Пол: Мужской
Сообщений: 3820


Все начинается с Value


« Ответ #19 : 30.10.2016, 17:39:52 »

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

Репутация: +798/-4
Offline Offline

Сообщений: 7776



« Ответ #20 : 30.10.2016, 17:49:52 »

простите, но это откровенно чушь. Лишь бы, что-то написать
Федор, вы можете не просить прощения, я на вас никогда не обижаюсь Azn

в этой статье да, действительно разные. но есть другие, в которых сравнивается одно и тоже. не обращал на это внимания, просто взял первую попавшуюся в качестве примера. смысл не в том, что выбираются разные данные, а в том, что в статье описан 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, 18:02:00 от dmitry_stas » Записан
zomby6888
Живу я здесь
******

Репутация: +168/-3
Offline Offline

Пол: Мужской
Сообщений: 1538


« Ответ #21 : 30.10.2016, 18:18:20 »

По моему эта функция просто не использует индексы. Вообще. Отсюда такой результат.
Записан
Fedor Vlasenko
Профи
********

Репутация: +696/-5
Offline Offline

Пол: Мужской
Сообщений: 3820


Все начинается с Value


« Ответ #22 : 30.10.2016, 18:26:09 »

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

Репутация: +798/-4
Offline Offline

Сообщений: 7776



« Ответ #23 : 30.10.2016, 18:35:02 »

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

Данные строки адресованы к автору статьи
тогда видимо моя очередь извиняться  drink
Записан
Septdir
Живу я здесь
******

Репутация: +36/-3
Offline Offline

Пол: Мужской
Сообщений: 841


Skype: septdir


« Ответ #24 : 30.10.2016, 18:37:00 »

использует, дело в другом. просто с SQL_CALC_FOUND_ROWS результат такой же, как если бы запрос был
Нет она быстрее. на мизер но быстрее.
Записан
dmitry_stas
Профи
********

Репутация: +798/-4
Offline Offline

Сообщений: 7776



« Ответ #25 : 30.10.2016, 18:43:21 »

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

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

P.P.S. проверил ради интереса на MariaDB - результат такой же.
« Последнее редактирование: 30.10.2016, 18:49:09 от dmitry_stas » Записан
Septdir
Живу я здесь
******

Репутация: +36/-3
Offline Offline

Пол: Мужской
Сообщений: 841


Skype: septdir


« Ответ #26 : 30.10.2016, 19:40:29 »

Ну если мечтать  то было не плохо получать тотал всегда. Без бубнов доп запросов под запросов и максимально быстро и оптимизированно.
Записан
Страниц: [1]   Вверх
  Добавить закладку  |  Печать  
 
Перейти в:  

Powered by SMF 1.1.21 | SMF © 2006, Simple Machines

Joomlaforum.ru is not affiliated with or endorsed by the Joomla! Project or Open Source Matters.
The Joomla! name and logo is used under a limited license granted by Open Source Matters
the trademark holder in the United States and other countries.

LiveInternet