Мне нужен оператор MySql, который выберет все строки, а также количество томов.
Я использовал
mysql_query("SELECT * FROM posts LIMIT 0, 5");
… пытаюсь добавить счетчик:
mysql_query("SELECT *, COUNT(*) AS total FROM posts LIMIT 0, 5");
… но это возвращает только одну строку.
Кроме того, если есть лучший способ получить общее количество, чем добавить дополнительный столбец в каждую строку, тогда я бы хотел этого. Спасибо!
Мне нужен оператор MySql, который выберет все строки, а также количество томов.
Когда принято буквально, это невозможно. Результатом SQL-запроса является (виртуальная) таблица; столбец в каждой строке в этой таблице результатов содержит значение, которое связано только с этой строкой, и строки действуют независимо друг от друга.
Существует множество способов захвата rowcount всего результата, но это делается либо в двух операциях, либо с запросом, который концептуально отличается от того, что у вас есть. (Решения ниже)
В вашем первоначальном вопросе есть один аспект, который можно интерпретировать несколькими способами:
а также сколько всего строк
Это может означать либо:
(Я придумаю ответы для обоих ниже)
но это возвращает только одну строку. Я предполагаю, что это потому, что COUNT (*) будет одинаковым для каждой строки, и по какой-то причине MySql возвращает только строки с уникальными значениями для него? Я понятия не имею.
COUNT
– это совокупная функция. Используя агрегированную функцию, вы просите базу данных группировать группы строк и проецировать некоторые ее аспекты в одну строку. Смущает то, что mysql также позволяет смешивать неагрегатные и агрегированные выражения в одном списке SELECT
. Большинство других баз данных не позволяют этого и дают вам ошибку для этого, но, увы, MySQL этого не делает.
Однако COUNT (*) все же объединяет все строки в одну строку, представляющую всю группу строк.
Кроме того, если есть лучший способ получить общее количество, чем добавить дополнительный столбец в каждую строку, тогда я бы хотел этого. Спасибо!
да, есть несколько способов.
Если вы хотите получить количество строк, возвращаемых на PHP, так что после того, как MySQL применил предложение limit, я предлагаю просто вызвать функцию php mysql_num_rows
( http://www.php.net/manual/en/function.mysql-num -rows.php ) после выполнения вызова mysql_query
.
Если вы хотите получить количество строк, которые были бы возвращены в отсутствие предложения LIMIT
, я предлагаю сделать это за 2 шага: во-первых, выполните небольшую измененную версию исходного запроса, а затем, сразу же после этого, вызовите MySQL FOUND_ROWS
. (см. http://dev.mysql.com/doc/refman/5.5/en/information-functions.html#function_found-rows )
Это будет выглядеть так:
$result = mysql_query('SELECT SQL_CALC_FOUND_ROWS * FROM posts LIMIT 0, 5'); //do stuff with the result, but don't do any other queries //get the total number of rows (disregarding the LIMIT clause) $result = mysql_query('SELECT FOUND_ROWS()');
Модификатор SQL_CALC_FOUND_ROWS
сообщает MySQL отслеживать общее количество строк перед применением предложения LIMIT
, а FOUND_ROWS()
возвращает это число. Помните о двух вещах:
mysql_query
должны выполняться по одному и тому же соединению mysql_query
другой запрос между этими вызовами в mysql_query
О, последнее замечание: при использовании LIMIT
вы обычно хотите, чтобы результаты упорядочивались определенным образом. Обычно люди используют LIMIT
для разбивки на страницы. Если вы не заказываете строки, порядок неопределен и последующие запросы могут возвращать строки, уже возвращенные предыдущими операциями, даже если смещение LIMIT
отличается. Вы можете явно упорядочить результат, используя предложение ORDER BY
. ( http://dev.mysql.com/doc/refman/5.5/en/select.html )
Я не уверен, на какую сумму вы думаете: общее количество выбранных или количество всех строк в целом таблице. Это возвращает числа всех строк в целом таблице, конечно, в каждой строке одно значение:
mysql_query("SELECT *, (select COUNT(*) from posts) AS total FROM posts LIMIT 0, 5");
Я думаю, вы слишком усложняете эту проблему. Я не вижу проблемы с использованием двух запросов.
Первый запрос для получения итоговых сообщений (я предполагаю, что вы хотите общее количество во всей таблице):
SELECT COUNT(*) AS total FROM posts;
И второе, чтобы запросить ваши сообщения:
SELECT * FROM posts LIMIT 0, 5
Причина в том, что не всегда полезно извлекать данные, используя более одного запроса, особенно когда это имеет смысл.
Если бы вы добавили его в качестве дополнительного столбца, используя, скажем, подзапрос, у вас было бы общее количество в каждой строке, но вы все равно в основном выполняли бы два запроса (или будет выполняться подзапрос для каждой строки, я не могу вспомнить ?)
Он также обеспечивает большую гибкость, чтобы получить счет сначала, поскольку некоторые запросы возвращают неверное общее количество в зависимости от того, насколько сложным является ваш запрос. И вам может потребоваться изменить запрос на подсчет, чтобы вы получили правильную сумму и можете правильно рисовать.
Например, в случае запроса от одного до многих, скажем, вы хотите получать сообщения и комментарии, вы получите неправильный счет, поскольку пост будет дублироваться для каждого комментария для этого сообщения.
Сокращенный пример:
post_id | comment_id 1 | 1 1 | 2 2 | 3 3 | 4 3 | 5
Чтобы сделать это правильно, сначала нужно запустить следующий запрос, чтобы получить общее количество сообщений:
SELECT COUNT(*) AS total FROM posts;
И тогда вам нужно будет запустить:
SELECT id FROM posts limit 0, 5;
И, наконец, вы запустите:
select p.id, c.id from posts p left join comments c on c.post_id = p.id where id in(id list from above query)
Очевидно, что ваш запрос не будет работать в вышеупомянутой проблеме. Но я просто пытаюсь проиллюстрировать, почему может быть полезно получить общее количество в отдельном запросе.