Как правильно организовать получение списка данных с дополнительным полем — количество?
Есть такой запрос:
public function getAll($data) { $params = [ 'user_id' => $data->user_id, 'period' => $data->period, 'limit' => $data->limit, 'offset' => $data->offset, ]; return $this->db->row('SELECT id, amount, DATE_FORMAT(date, "%d.%m.%Y %H:%i:%s") as date FROM enrollments WHERE user_id = :user_id && status = 1 && UNIX_TIMESTAMP(date) > :period ORDER BY id DESC LIMIT :limit OFFSET :offset', $params); } |
public function getAll($data) { $params = [ 'user_id' => $data->user_id, 'period' => $data->period, 'limit' => $data->limit, 'offset' => $data->offset, ]; return $this->db->row('SELECT id, amount, DATE_FORMAT(date, "%d.%m.%Y %H:%i:%s") as date FROM enrollments WHERE user_id = :user_id && status = 1 && UNIX_TIMESTAMP(date) > :period ORDER BY id DESC LIMIT :limit OFFSET :offset', $params); }
Хочется, чтобы этот запрос возвращал и количество данных всего - без offset и limit, но помещал их отдельно от массива элементов, можно ли как-то это сделать?
Мне очень не хочется делать отдельный второй запрос на подсчет элементов.
Дополнительно:
Akina я правильно понимаю, что с cte, count(*) over () будет зависеть от реализации, но в целом скорее всего будет медленнее?
COUNT() - функция детерминированная, даже в оконном варианте, так что итог её работы ну никак не может зависеть от реализации. Ни от диалекта, ни от версии, ни от иных факторов. Да и что может повлиять на подсчёт записей? сколько есть, столько и есть...
Насчёт медленнее - в подавляющем большинстве случаев само по себе вычисление результата функции не должно зависеть от того, в CTE она или нет.
Хочется, чтобы этот запрос возвращал и количество данных всего - без offset и limit, но помещал их отдельно от массива элементов, можно ли как-то это сделать?
Мне очень не хочется делать отдельный второй запрос на подсчет элементов.
Если формализовать эту хотелку, то она будет звучать так: я хочу в одном запросе получить данные для различных уровней группировки. Что вряд ли является идеологически верным желанием (исключение - группирующий запрос с WITH ROLLUP). Так что я бы сказал, что выполнение отдельного запроса для получения количества записей - это правильное решение, а попытка всё запихать в один запрос - нет. Но выбор за Вами...
Будет ли подсчет при её использовании таким же быстрым, как count() отдельным запросом, или таким же медленным, как подсчет с помощью SQL_CALC_FOUND_ROWS.
И нет, в общем случае от того, где COUNT OVER находится, в основном запросе или в CTE, скорость подсчёта никак не зависит. Зависит исключительно от того, как именно сервер собрался сортировать и подсчитывать. Есть, конечно, частные случаи, скажем, старые версии постгресса, которые в обязательном порядке материализуют CTE - понятно, что в этом случае подсчёт в запросе быстрее за счёт меньшего количества дисковых операций.
А что мешает после получения всех элементов просто взять размер полученного массива?
- Исправил вопрос (некорректно изначально выразил мысль).
Я беру с лимитом по 10, а нужно узнать, сколько всего, без данного параметра.
Это в любом случае нужно делать еще один запрос? - lexstile, Да. Нужно делать запрос на COUNT(*)
- Rsa97, то есть, получится, что-то такое?
public function getCount($data) { $params = [ 'user_id' => $data->user_id, 'period' => $data->period, ]; return $this->db->row('SELECT COUNT(*) FROM enrollments WHERE user_id = :user_id && status = 1 && UNIX_TIMESTAMP(date) > :period', $params); }
public function getCount($data) { $params = [ 'user_id' => $data->user_id, 'period' => $data->period, ]; return $this->db->row('SELECT COUNT(*) FROM enrollments WHERE user_id = :user_id && status = 1 && UNIX_TIMESTAMP(date) > :period', $params); }
- lexstile, Да. Для удобства доступа к полю можно записать COUNT(*) AS `count`.
- или не дописывать, если в классе db есть метод column(), а возвращать сразу его результат
- Роман Юрьевич Ипатьев, вы правы, я про него совсем забыл.
Без дополнительного запроса нельзя.
Есть разные ухищрения, которые позволят замаскировать дополнительный запрос, но по факту это будет именно он.
Но при этом есть риск натупить с производительностью.
Так что лучше не пытаться усидеть на двух стульях одной, ээээ..., туловищем, а сделать два отдельных запроса.
Да, это неудобно. Но неправильный подсчет полного количества строк на большой таблице может создать очень сильную нагрузку, вплоть до того, чтобы полностью положить систему. Так что лучше не экспериментировать
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Для организации получения списка данных с дополнительным полем — количество, можно воспользоваться следующим подходом:
1. Создайте запрос к базе данных, который выбирает необходимые данные и подсчитывает количество записей. Например, для языка программирования PHP это может выглядеть следующим образом:
$query = "SELECT *, COUNT(*) as count FROM table_name GROUP BY column_name"; $result = mysqli_query($connection, $query); while($row = mysqli_fetch_assoc($result)) { echo "Field 1: " . $row['field1'] . "<br>"; echo "Field 2: " . $row['field2'] . "<br>"; echo "Count: " . $row['count'] . "<br>"; }
2. Обработайте результат запроса и выведите необходимые данные, включая количество записей.
3. Если вы хотите отобразить данные на веб-странице, вы можете использовать HTML и CSS для оформления списка данных. Например:
echo "<ul>"; while($row = mysqli_fetch_assoc($result)) { echo "<li>Field 1: " . $row['field1'] . "</li>"; echo "<li>Field 2: " . $row['field2'] . "</li>"; echo "<li>Count: " . $row['count'] . "</li>"; } echo "</ul>";
Таким образом, вы сможете получить список данных с дополнительным полем — количество, и отобразить его на веб-странице. Не забудьте подставить свои реальные данные и настройки подключения к базе данных для корректной работы кода.