Подтвердить что ты не робот

Подготовленный оператор `WHERE.. IN (..)` запрос и сортировка - с MySQL

Представьте, что у нас есть запрос:

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();
    }

Но теперь мне придется сортировать результаты вручную. Есть ли у меня хорошие альтернативы?

4b9b3361

Ответ 1

вы могли бы сделать это следующим образом:

$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.

Ответ 2

Я считаю, что это самый простой ответ:

$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

Я добавлю в конечном итоге медленное и уродливое решение, которое, тем не менее, использует подготовленные инструкции для ЛЮБОГО количества элементов массива:) 3 утверждения универсальны для любого случая и могут быть повторно использованы повсюду.

  • CREATE TEMPORARY TABLE Идентификаторы ( идентификатор INT );
  • INSERT INTO ids VALUES(?); это вставляет ваши идентификаторы
  • SELECT id FROM ids LEFT JOIN .... ; использовать данные из других таблиц для сортировки списка ids
  • SELECT id FROM ids ; выберите все обратно

В противном случае вам придется использовать IN (?,?,?,.... или отсортировать строки вручную. Лучшая идея - использовать простые MySQL-запросы или попытаться получить список идентификаторов, уже отсортированных так, как вам нравится.

Ответ 4

Альтернативой может быть использование функции usort PHP для объекта результата, но это "руководство".

Смотрите это: Сортировка объекта в PHP

Ответ 5

Имела ту же проблему и в дополнение к ответу @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();

Ответ 6

Нет, это не рекомендуется, если вы хотите получить определенные записи из базы данных с помощью предложения ORDER BY.

Ответ 7

Рассматривали ли вы переписывание исходного запроса с помощью предложения JOIN и WHERE, чтобы получить IDS, чтобы избежать необходимости в предложении WHERE IN? Я пришел сюда с тем же вопросом, и после рассмотрения возможных решений я понял, что INNER JOIN был моим решением.