Count sql php
Выводим количество записей в таблице MySQL
Здравствуйте, уважаемый посетитель!
Прежде, чем приступит к следующей теме и заняться формами, хочу затронуть еще один вопрос по работе с базой данных MySQL, который был задан одним из пользователей. А именно: как вывести суммарное количество записей в таблице MySQL.
Ранее, в разделе Работа с БД MySQL, довольно подробно рассматривались различные действия с БД MySQL, от подключения к ней, до ввода/вывода данных. При этом, понятно, что имеется множество возможных операций с базой данных, и заведомо предусмотреть все случаи просто невозможно.
Однако, если появился конкретный вопрос, то считаю, его необходимо рассмотреть отдельно. Тем более, что такие задачи нередко могут возникать при работе с БД. И делать это будем на примере таблицы базы данных «url», которая используется для формирования динамических страниц создаваемого сайта «newsite.local».
- Вариант с использованием SQL-функции count()
- Вариант с использованием PHP-функции count()
- Вариант с использованием PHP-функции mysqli_num_rows
- Исходные файлы сайта
Вариант с использованием SQL-функции count()
Как отмечалось выше, здесь для примера будем использовать таблицу «url», которая на данный момент содержит 6 строк. Ниже приведен скриншот ее содержимого, сделанного с помощью веб-приложения «phpMyAdmin».
Рис.1 Скриншот содержимого таблицы «url»
Для вывода количества записей можно использовать разные способы. При этом, какой применять, в большой степени зависит от конкретной задачи.
Например, если требуется определить только число строк, без выполнения с ней каких-либо других операций, вполне уместно использовать SQL-функцию «count()». Которая возвращает эту величину в соответствии с определенными критериями.
В этом случае SQL-запрос будет иметь следующий вид: «SELECT COUNT(имя поля) FROM имя_таблицы WHERE условие». При этом, если вместо имени поля указать «*» и не применять условие, то будут подсчитаны абсолютно все имеющиеся записи без каких-либо условий.
Вот такой запрос для нашей задачи, где требуется определить все суммарные записи в таблице, мы и применим. А для этого воспользуемся аналогичными, ранее составленными PHP-функциями, предназначенными для работы с базой данных MySQL.
В данном случае за основу возьмем функцию по выводу одиночной строки, заменив в ней кроме имени и параметров еще и SQL-запрос на «SELECT COUNT(*) FROM `$table`». А также ассоциативный массив на числовой, в качестве ключей которого будут использоваться не наименования полей, а числовые индексы.
Следует отметить, что получить количество записей можно и не составляя отдельную функцию, а разместив необходимый скрипт непосредственно на HTML-странице. Однако, в этом случае такое решение будет не универсально, при котором потребуется каждый раз использовать один и тот же код при выполнении однотипных действий.
В нашем варианте, используя в качестве параметра имя таблицы, можно такую функцию использовать при определении количества всех строк для разных случаев.
Для этого при ее вызове понадобится всего лишь в качестве аргумента указать имя таблицы — остальное будет выполняться составленной для этой цели универсальной функцией. PHP-код такой пользовательской функции приведен на рис.1.
query ( «SELECT COUNT(*) FROM `$table`» )) <
die (‘При извлечении записей возникла ошибка: ‘ .$mysqli->errno. ‘ — ‘ .$mysqli->error );
mysql_num_rows
mysql_num_rows — Возвращает количество рядов результата запроса
Данное расширение устарело, начиная с версии PHP 5.5.0, и удалено в PHP 7.0.0. Используйте вместо него MySQLi или PDO_MySQL. Смотрите также инструкцию MySQL: выбор API и соответствующий FAQ для получения более подробной информации. Альтернативы для данной функции:
Описание
Возвращает количество рядов результата запроса. Эта команда работает только с запросами SELECT или SHOW, возвращающих актуальный результат запроса. Чтобы получить количество рядов, обработанных функциями INSERT, UPDATE, REPLACE и DELETE, используйте функцию mysql_affected_rows() .
Список параметров
Обрабатываемый результат запроса. Этот результат может быть получен с помощью функции mysql_query() .
Возвращаемые значения
Количество рядов в результате запроса в случае успеха или FALSE в случае возникновения ошибки.
Примеры
Пример #1 Пример использования mysql_num_rows()
Примечания
Замечание:
При использовании mysql_unbuffered_query() функция mysql_num_rows() не вернёт корректного значения до тех пор, пока все ряды не будут получены.
Замечание:
Для обратной совместимости может быть использован следующий устаревший псевдоним: mysql_numrows()
Смотрите также
- mysql_affected_rows() — Возвращает число затронутых прошлой операцией рядов
- mysql_connect() — Открывает соединение с сервером MySQL
- mysql_data_seek() — Перемещает внутренний указатель в результате запроса
- mysql_select_db() — Выбирает базу данных MySQL
- mysql_query() — Посылает запрос MySQL
User Contributed Notes 22 notes
Some user comments on this page, and some resources including the FAQ at :
This is not a particularly universal solution, and those who read these comments on this page should also be aware that
select count(*) may not give correct results if you are using «group by» or «having» in your query, as count(*) is an agregate function and resets eachtime a group-by column changes.
select sum(..) . left join .. group by . having .
can be an alternative to sub-selects in mysql 3, and such queries cannot have the select fields replaced by count(*) to give good results, it just doesn’t work.
I may indeed be the only one ever to encounter this — however if you have a myisam table with one row, and you search with valid table and column name for a result where you might expect 0 rows, you will not get 0, you will get 1, which is the myisam optimised response when a table has 0 or one rows. Under «5.2.4 How MySQL Optimises WHERE Clauses» it reads:
*Early detection of invalid constant expressions. MySQL quickly detects that some SELECT statements are impossible and returns no rows.
*All constant tables are read first, before any other tables in the query. A constant table is:
1) An empty table or a table with 1 row.
2) A table that is used with a WHERE clause on a UNIQUE index, or a PRIMARY KEY, where all index parts are used with constant expressions and the index parts are defined as NOT NULL.
Hopefully this will keep someone from staying up all night with 1146 errors, unless I am completely mistaken in thinking I have this figured out.
Re my last entry:
This seems the best workaround to get an ‘ordinary’ loop going, with possibility of altering output according to row number
(eg laying out a schedule)
SELECT SQL_CALC_FOUND_ROWS together with
SELECT FOUND_ROWS()
Only worked with the following syntax:
$result = @mysql_query($query);
$resultTotal = @mysql_query(«SELECT FOUND_ROWS()»);
$res= mysql_fetch_array($resultTotal);
echo $res[‘FOUND_ROWS()’];
In Reply to the last post: This may not always work correctly, as $object->doesExist would contain a result, not a boolean value. A better way (using the same method) would be using a cast:
doesExist = (bool) ( $res = mysql_fetch_array ( $result ))
[. ]
>
>
?>
After all there is an array of row arrays, as signified by
mysql_num_rows($result):
Say this gives «40 rows» : it would be useful to know when the iteration is on row 39.
The nearest seems to be «data seek»:but it connects directly to a
row number eg (from mysql_data_seek page)
for ($i = mysql_num_rows($result) — 1; $i >= 0; $i—) <
if (!mysql_data_seek($result, $i)) <
echo «Cannot seek to row $i: » . mysql_error() . «n»;
continue;
>
= it still wouldn’t solve knowing what row number you’re on in an ordinary loop.
One reason for this situation is the php fetch (fetch-a-single-row) construction, without any reasonable FOR loop possibility with row numbers.
Suggestion:
$Rows[$i] possibility where
$i would be the row number
$Rows[$row[], $row[], $row[]. ]
0 1 2 etc
— the excellent retrieval WITHIN a row ( $row[$i] ),
while certainly more important, is not matched by
similar possibilities for rows themselves.
and Count($result) doesnt work of course, $result being a
mere ticket-identifier.
In response to oran at trifeed dot com:
You are only experiencing this behaviour because you have not given your FOUND_ROWS() result an alias:
$qry = mysql_query ( ‘SELECT FOUND_ROWS() AS total’ );
$rst = mysql_fetch_array ( $qry, MYSQL_ASSOC );
echo $rst[‘total’];
MySQL 4.0 supports a fabulous new feature that allows you to get the number of rows that would have been returned if the query did not have a LIMIT clause. To use it, you need to add SQL_CALC_FOUND_ROWS to the query, e.g.
$sql = «Select SQL_CALC_FOUND_ROWS * from table where state=’CA’ limit 50»;
$result = mysql_query($sql);
$sql = «Select FOUND_ROWS()»;
$count_result = mysql_query($sql);
You now have the total number of rows in table that match the criteria. This is great for knowing the total number of records when browsing through a list.
A note on the following usage; that suggest to use several MySQL Functions to get the number of Table Records.
You may be familiar with following:
I omitted the actual connection to MySQL and the execution of the query, but you get the idea.
I did some tests and on a fairly high traffic web site, one that executes several queries quite often and found that using this combination of MySQL Functions can actually result in wrong results.
For example, assume I have two queries to get the number of Table Records in two different Tables. So in essence, we are executing 4 queries ( 2 queries for each Table ).
If two different requests come in through PHP, your going to run into problems. Note than when I mean request, I mean two different clients requesting your PHP page.
Execute: SQL_CALC_FOUND_ROWS On Table 1
Execute: SQL_CALC_FOUND_ROWS On Table 2
Execute: Select FOUND_ROWS( )
At this point, you see the race condition that occurred. While Request 1 was being executed, Request 2 came in.
At this point Request 1 will return the number of Table Records in Table 2 and not Table 1 as expected!
Why? Because MySQL does not differ between requests. Each query is in a queue waiting its turn. As soon as its turn comes in it will be executed my MySQL.
The MySQL Function Select FOUND_ROWS( ) will return the result of the last SQL_CALC_FOUND_ROWS!
In preventing the race condition for the SQL_CALC_FOUND_ROWS and FOUND_ROWS() operations, it can become complicated and somewhat kludgy to include the FOUND_ROWS() result in the actual result set, especially for complex queries and/or result ordering. The query gets more complex, you may have trouble isolating/excluding the FOUND_ROWS() result, and mysql_num_rows() will return the number of actual results + 1, all of which makes your code messier and harder to read. However, the race condition is real and must be dealt with.
A alternative and cleaner method is to explicitly lock the table using a WRITE lock (preventing other processes from reading/writing to the table). The downsides I can see are a performance hit, and your mysql user must have lock permissions.
query ( «LOCK TABLE t WRITE» );
$results = $mysqli -> query ( «SELECT id FROM t LIMIT 0,10» );
$totalNumResults = array_pop ( $mysqli -> query ( «SELECT FOUND_ROWS()» )-> fetch_row ());
$mysqli -> query ( «UNLOCK TABLES» );
?>
Now you may iterate through the results just like any other result set.
In one of my applications, I had to let an object know wether it exists in the database or not. I found a cheap solution w/o the usage of mysql_num_rows():
doesExist = ( $res = mysql_fetch_array ( $result ))
[. ]
>
>
?>
When mysql.trace_mode = On, SELECT FOUND_ROWS() allway returns 0. It looks like a bug.
If you have a table with 5 rows and issue:
SELECT SQL_CALC_FOUND_ROWS * FROM table LIMIT 1;
mysql_num_rows() returns 1 as expected.
If you issue «SELECT FOUND_ROWS()» just in sequence, in the same connection resource, it allways returns 0 rather than expected 5.
Just switch mysql.trace_mode to Off and things will work.
To use SQL COUNT function, without select the source.
Thanks, good luck.
Actually I am a little ashamed to be saying this, but I stand corrected about a rather old note I posted on 17-Jul-2007 06:44.
Using SQL_CALC_FOUND_ROWS and FOUND_ROWS( ) will NOT trigger a race condition on MySQL, as that would pretty much defy their entire purpose.
The results for their usage is actually unique per connection session as it is impossible for processes to share anything in PHP. As far as PHP is concerned, each request represents a new connection to MySQL as each request is isolated to its own process.
To simulate this, create the following script:
Set the connection and query information for something that matches your environment.
Run the script once with the Sleep query string and once again without it. Its important to run them both at the same time. Use Apache ab or something similar, or even easier, just open two browser tabs. For example:
If a race condition existed, the results of the first instance of the script would equal the results of the second instance of the script.
For example, the second instance of the script will execute the following SQL query:
This happens while the first instance of the script is sleeping. If a race condition existed, when the first instance of the script wakes up, the result of the FOUND_ROWS( ) it executes should be the number of rows in the SQL query the second instance of the script executed.
But when you run them, this is not the case. The first instance of the script returns the number of rows of its OWN query, which is:
So it turns out NO race condition exists, and every solution presented to combat this «issue» are pretty much not needed.
Все способы, как определить количество строк в MySQL
Дата публикации: 2016-05-27
От автора: один мой знакомый утверждает, что Дед Мороз существует. В него он поверил после того, как его младшему сыну на Новый Год подарили 10 кг шоколадных конфет. Теперь на следующий год придется у Деда Мороза просить пломбы для всех членов семьи! К счастью в веб-программировании можно перестраховаться от таких неожиданностей, и определить количество строк в MySQL заранее.
Зачем знать сколько?
Любая таблица состоит из столбцов и строк. Объем хранящихся в базе данных зависит от того, сколько строк содержится в каждой ее таблице.
Подобно тому, как число дырок в зубах человека зависит от съеденного ранее объема конфет. Точнее, от общего веса сладостей, которым «одарили» вашего ребенка на Новый Год .
Понятно, что от большого числа строк в базе MySQL пломб во рту не прибавится, но все же знание этого параметра может понадобиться при оптимизации работы вашего сайта, для запуска некоторых скриптов и т.д.
Легко!
Для получения в MySQL количества строк не обязательно «кумекать» в составлении SQL-запросов. Достаточно просто открыть в программной оболочке нужную таблицу и посмотреть id последней строки. Именно этот столбец чаще всего используют в качестве уникального ключа, и его значение генерируется автоматически (автоинкремент) путем приращения единицы(+1) к предыдущему.
Бесплатный курс по PHP программированию
Освойте курс и узнайте, как создать динамичный сайт на PHP и MySQL с полного нуля, используя модель MVC
В курсе 39 уроков | 15 часов видео | исходники для каждого урока
Чтобы доказать эту «аксиому», откроем в phpMyAdmin таблицу любой БД. Например, таблицу animal. Как видно на скриншоте, значение столбца id идет по порядку, от 1 до.… Так, отставить! А куда убежал котяра с «идентификационным номером» 4? Наверное, опять «собачек» под номерами 5 и 6 испугался
В этой базе MySQL количество строк в таблице можно просто посчитать «на пальцах». Но что делать, если в таблице не 7 строк, а несколько сотен? Например, как в этой.
И это лишь одна из восьми страниц выборки. На самом деле число записей может исчисляться не только сотнями, но и тысячами. Вдобавок здесь нет столбца id, потому что он не является обязательным. Его наличие зависит от структуры всей БД, поскольку в ней значения всех строк взаимосвязаны между собой. Получается, что описанный выше метод подсчета строк MySQL не всегда действует.
Несколько правильных методов
Как говорится, первый метод «комом», поэтому рассмотрим несколько более эффективных и менее «простых» способов:
Функция COUNT() – возвращает число строк. Является встроенной функцией SQL. Все таки давайте узнаем, количество записей большой таблицы из БД, скриншот которой приведен выше. Код запроса:
Как узнать количество записей в SQL-выборке
Очень часто нам не требуется извлекать данные из таблицы, однако, нам необходимо узнать количество записей в определённой SQL-выборке, в частном случае, количество записей в таблице. Вот как узнать количество записей в SQL-выборке, я расскажу в этой небольшой статье.
На самом деле всё очень просто, и нам нужна всего лишь функция COUNT():
SELECT COUNT(*) FROM `table` WHERE `field_1`=’value_1′
После выполнения данного запроса будет возвращён result_set, в котором будет храниться массив, содержащий элемент COUNT(*) со значением количества записей в таблице «table«, где поле «field_1» имеет значение «value_1«.
Другой пример. Допустим, надо узнать просто количество записей. Тогда то же самое, но без WHERE:
SELECT COUNT(*) FROM `table`
И давайте, напоследок, подкину ещё один пример. Допустим, Вам необходимо подсчитать количество уникальных записей в таблице:
SELECT COUNT(DISTINCT `field_1`) FROM `table`
Вот такой нехитрой функцией COUNT() можно легко узнавать количество записей в SQL-выборке, не извлекая при этом сами записи и экономя ресурсы.
Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (http://myrusakov.ru)!
Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/rusakovmy.
Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления
Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.
Порекомендуйте эту статью друзьям:
Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):
Она выглядит вот так:
Комментарии ( 45 ):
Михаил, здравствуйте! Хотел бы попросить у Вас помощи. Почему на реальном хостинге этот запрос не работает $res_articles = $mysqli->query(«SELECT id,title,cp_title,description,images,author,DATE_FORMAT(date,’%d %M %Y’) as date FROM articles WHERE tg=’0′ ORDER BY id DESC LIMIT $shift,$num_data»); Проблема в — LIMIT $shift,$num_data — не пойму почему не работает с переменными! Перепробовал все варианты, уже два дня голову ломаю :((( Если Вас не затруднит можете дать совет.
Вряд ли дело в хостинге, Вы проверьте значения переменных shift и num_data. А также «не работает» понятие растяжимое. Выдаются ли какие-нибудь ошибки? Или просто пустой результат выходит?
Пустой результат, но когда убираю LIMIT $shift,$num_data или пишу вместо переменных LIMIT 2, 5 то всё ОК. А может переменные привести к числу через integer?
Тогда проблема в значении переменных, можете ещё попробовать через соединение строк: «LIMIT «.$shift.», «.$num_data
Я так пробовал всё равно пустой результат, но в переменных лежат числа я проверял конечно я не проверял на int
Посмотрите, что в этой строке (всё ли правильно): echo «SELECT id,title,cp_title,description,images,author,DATE_FORMAT(date,’%d %M %Y’) as date FROM articles WHERE tg=’0′ ORDER BY id DESC LIMIT $shift,$num_data»;
Сейчас проверяю, главное что на localhoste всё работает
Вывод после echo — SELECT id,title,cp_title,description,author,images,DATE_FORMAT(date,’%d %M %Y’) as date FROM articles WHERE tg=’0′ ORDER BY id DESC LIMIT -10,10.
Видите, что запрос неправильный? Вот и подумайте, почему -10 подставляется.
Спасибо Михаил за помощь разобрался просто в функции не изменил один параметр
PHP MySQL COUNT
Гость
Прошу помощи. Имеется массив
$artists = array (
«Айвазовский Иван (Aivazovsky Ivan Constantinovich)»=>»Aivazovsky Ivan Constantinovich»,
«Аверкамп Хендрик (Avercamp Hendrick)»=>»Avercamp Hendrick»,
… Итд… Всего около 300);
/***************************/
Имеем таблицу в базе, у которой значение поля artist_name = Aivazovsky Ivan Constantinovich или Avercamp Hendrick и так далее. Всего записей в таблице около 150 тысяч
Задача сводиться к тому, что б на сайте вывести весь список художников с количеством записей того или иного художника в базе. То есть В таком виде
1Аверкамп Хендрик (Avercamp Hendrick)(21)
2 Айвазовский Иван (Aivazovsky Ivan Constantinovich)(139)
3 Александер Джон (Alexander John)(25)
4 Алма-Тадема (Alma-Tadema Lawrence)(256)
5 Ангиссола Софонисба (Sofonisba Anguissola)(43)
6 Андреотти Федерико (Andreotti Federico)(15)
7 Анжелико Фра (Angelico Fra)(102)
итд.
Напомню, Значение берем из массива $artists и этому значению соотвецтвует поле artist_name.
Я делал двумя способами, но это очень медленно
1 способ (считает сама база)
foreach ($artists as $key)
<
$query = mysql_query(«SELECT COUNT(*) FROM ‘gallery’ WHERE artist_name=’$value'»);
$row = mysql_fetch_row($query);
echo »
$key ($row[0]) «;
>
2 способ
$query = mysql_query(«SELECT artist_name FROM ‘posterlux_gallery'»); //выбераем одним запросом все artist_name из базы
while($result = mysql_fetch_assoc($query.
<
$resultvalue[] = $result[‘artist_name’]; //переводим всё в огромный массив
>
foreach($artists as $key => $value)
<
$count = 0;
foreach ($resultvalue as $b) //ну и собственно пробегаемся по массиву и подсчитываем
<
if($b == $value) $count = ++$count;
>
echo »
>$key ($count) «;
>
То есть Получается ещё медленнее чем первый вариант.
Помогите. Как правильно сделать?
Дополнено (1). $query=»SELECT COUNT(*) AS count, artist_name FROM posterlux_gallery GROUP BY artist_name»;
$result=mysql_query($query);
$row=mysql_fetch_assoc($result);
do
<
foreach($artists as $key=>$value)
<
if($value==$row[‘artist_name’])
>
while($row=mysql_fetch_assoc($result. ;
— спасибо за этот вариант, но есть ещё один вопрос, массив $artists сортирован ksort, а при таком выводе сбивается алфавитный порядок художников, как быть?
skeef
В любом случае быстрее чем может сделать база не получится, по этому скорость надо добиваться от базы.
Поля индексированы? Конкретно artist_name?
Далее
Лучше разбить на 3 поля f_name, name и m_name и проиндексировать каждое поле символам по 3-4.
Производительность увеличится однозначно и в разы
удачи
MapbeBu4
Ну немножко улучшит ситуацию с 1-м способом добавления индекса на поле artist_name, а вообще я думаю стоит переписать скрипт таким образом, чтобы когда заполняется массив с артистами этим же запросом сразу считать количество записей по каждому артисту. А то получается, что вы в цикле исполняете огромное количество запросов, это не оптимально по сравнению с одним, но сложным запросом.
kashpur_kostya
Лучше создать таблицу в БД artists вместо массива и потом все одним запросом выбрать, так будет быстрее,
но для Вашего случая вот вариант:
$query=»SELECT COUNT(*) AS count, artist_name FROM posterlux_gallery GROUP BY artist_name»;
$result=mysql_query($query);
$row=mysql_fetch_assoc($result);
do
<
foreach($artists as $key=>$value)
<
if($value==$row[‘artist_name’])
>
while($row=mysql_fetch_assoc($result. ;
То что Вы написали:
1. Не нужно обращяться к бд пробегая по массиву, куча запросов(результат-медленная работа)
2. Не нужно загонять в массив, а потом его переберать…, лишняя работа(результат-медленная работа)
Galbarad
Може поможет запрос
select artist_name, Count(*)
from galery
group by artist_name
так одним запросом получаем и список артистов и количсетво в базе
ох, простите не внимательно прочитал ответ kashpur_kostya
не надо бегать по массивам
вот такой код подойдет я думаю
$query=»SELECT COUNT(*) AS count, artist_name FROM posterlux_gallery GROUP BY artist_name»;
$result=mysql_query($query);
while($row=mysql_fetch_assoc($result. <
print $artists[$row[‘artist_name’]].'(‘.$row[‘count’].’)’;
>