Представьте, что у нас есть запрос:
SELECT * FROM somewhere WHERE `id` IN(1,5,18,25) ORDER BY `name`;
и массив идентификаторов для извлечения: $ids = array(1,5,18,25)
В подготовленных заявлениях рекомендуется подготовить одно заявление и называть его несколько раз:
$stmt = $mysqli->prepare('SELECT * FROM somewhere WHERE `id`=?;'); foreach ($ids as $id){ $stmt->bind_params('i', $id); $stmt->exec(); }
Но теперь мне придется сортировать результаты вручную. Есть ли у меня хорошие альтернативы?
вы можете сделать это так:
$ids = array(1,5,18,25); // creates a string containing ?,?,? $clause = implode(',', array_fill(0, count($ids), '?')); $stmt = $mysqli->prepare('SELECT * FROM somewhere WHERE `id` IN (' . $clause . ') ORDER BY `name`;'); call_user_func_array(array($stmt, 'bind_param'), $ids); $stmt->execute(); // loop through results
Используя это, вы вызываете bind_param для каждого идентификатора, и у вас есть сортировка, выполняемая mysql.
Я считаю, что это самый простой ответ:
$ids = [1,2,3,4,5]; $pdos = $pdo->prepare("SELECT * FROM somwhere WHERE id IN (:" . implode(',:', array_keys($ids)) . ") ORDER BY id"); foreach ($ids as $k => $id) { $pdos->bindValue(":". $k, $id); } $pdos->execute(); $results = $pdos->fetchAll();
До тех пор, пока ваш массив идентификаторов не содержит ключей или ключей с незаконными символами, это будет работать.
Я добавлю в конечном итоге медленное и уродливое решение, которое, тем не менее, использует подготовленные инструкции для ЛЮБОГО количества элементов массива :). 3 утверждения универсальны для любого случая и могут быть повторно использованы повсюду.
CREATE TEMPORARY TABLE
идентификаторы (
id INT );
INSERT INTO
ids VALUES(?);
это добавит ваши идентификаторы SELECT
id FROM
ids LEFT JOIN .... ;
использовать данные из других таблиц для сортировки списка ids
SELECT
id FROM
id ;
выбрать все назад В противном случае вам придется использовать IN (?,?,?,....
или сортировать строки вручную. Лучше всего использовать простые MySQL-запросы или попытаться получить список идентификаторов, уже отсортированных в пути тебе нравится.
Нет, это не рекомендуется, если вы хотите получить определенные записи из базы данных, используя предложение ORDER BY
.
Альтернативой может быть использование функции usort PHP для объекта результата, но это «руководство».
См. Так: Сортировка объекта в PHP
Имела та же проблема и в дополнение к ответу @sled 7 лет назад, здесь есть возможность без создания call_user_func_array(array($stmt, 'bind_param'), $ids);
шаг, но только вызовите bind_params один раз:
$ids = array(1,5,18,25); // creates a string containing ?,?,? $bindClause = implode(',', array_fill(0, count($ids), '?')); //create a string for the bind param just containing the right amount of iii $bindString = str_repeat('i', count($ids)); $stmt = $mysqli->prepare('SELECT * FROM somewhere WHERE `id` IN (' . $bindClause . ') ORDER BY `name`;'); $stmt->bind_params($bindString, ...$ids); $stmt->execute();
Рассматривали ли вы переписывание исходного запроса с помощью предложения JOIN и WHERE, чтобы получить IDS, чтобы избежать необходимости в предложении WHERE IN? Я пришел сюда с тем же вопросом, и после рассмотрения возможных решений я понял, что INNER JOIN был моим решением.