MySql выбирает количество строк в качестве дополнительного столбца?
Мне нужен оператор MySql, который будет выбирать все строки, а также сколько всего строк есть.
Я использовал
mysql_query("SELECT * FROM posts LIMIT 0, 5");
...попытка добавить число:
mysql_query("SELECT *, COUNT(*) AS total FROM posts LIMIT 0, 5");
...но это возвращает только одну строку.
Кроме того, если есть лучший способ получить итог, чем добавить дополнительный столбец в каждую строку, то я бы хотел, чтобы это было так. Спасибо!
3 ответов:
Если понимать это буквально, то это невозможно. Результатом SQL-запроса является (виртуальная) таблица; столбец в каждой строке этой таблицы результатов предоставляет значение, связанное только с этой строкой, и строки фактически независимы друг от друга.Мне нужен оператор MySql, который будет выбирать все строки, а также сколько всего строк есть.
Есть много способов захватить количество строк всего результата, но это либо делается в двух операторах, либо с запросом, который концептуально отличается от того, что у вас есть. (Решения ниже)
В вашем исходном вопросе есть один аспект, который можно интерпретировать по-разному:А также сколько всего строк
Это может означать либо:
- подсчитайте каждую строку, возвращенную в результате.
- подсчитайте каждую строку, которая была бы возвращена, если бы не предложение LIMIT (которое усекает результат до 5 строк в этом случае). дело)
(я придумаю ответы на оба вопроса ниже)
Но это возвращает только одну строку. Я предполагаю, что это потому, что 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 этапа: сначала выполните слабо измененную версию исходного запроса, а затем затем, непосредственно после этого, вызовите функцию MySQLFOUND_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()возвращает это число. Имейте в виду 2 вещи:
- оба эти вызова
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Причина в том, что не всегда плохо извлекать данные с помощью нескольких запросов, особенно когда это имеет смысл.
Если бы вы добавили его в качестве дополнительного столбца, используя, скажем, подзапрос, вы бы получили итог в каждая строка, но вы все равно будете выполнять два запроса (или подзапрос будет выполняться для каждой строки, я не могу вспомнить?)
Это также обеспечивает большую гибкость, чтобы получить счетчик первым, так как некоторые запросы будут возвращать неправильное общее количество в зависимости от того, насколько сложен ваш запрос. И вам может потребоваться изменить запрос count, чтобы получить правильный итог и правильно разбить его на страницы.
Например, в случае запроса один ко многим, скажем, вы хотите получить сообщения и комментарии, вы получите неправильный подсчет, так как сообщение будет дублироваться для каждого комментария к этому сообщению.
Сокращенный пример:
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)Очевидно, что ваш запрос не столкнется с вышеуказанной проблемой. Но я просто пытаюсь проиллюстрировать, почему может быть полезно получить общее количество в отдельном запросе.
Comments