一个准备好的语句,`WHERE .. IN(..)`查询和排序 - 用MySQL

时间:2010-09-13 18:12:47

标签: php mysql mysqli prepared-statement mergesort

想象一下,我们有一个查询:

SELECT * FROM somewhere WHERE `id` IN(1,5,18,25) ORDER BY `name`;

以及要获取的ID数组:$ids = array(1,5,18,25)

准备好的语句是adviced准备一个语句并多次调用它:

$stmt = $mysqli->prepare('SELECT * FROM somewhere WHERE `id`=?;');
foreach ($ids as $id){
    $stmt->bind_params('i', $id);
    $stmt->exec();
    }

但现在我必须手动对结果进行排序。我有什么好的选择吗?

7 个答案:

答案 0 :(得分:21)

你可以这样做:

$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

使用这个你为每个id调用bind_param,你有mysql完成的排序。

答案 1 :(得分:5)

我相信这是最简单的答案:

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

很久你的Ids数组不包含带有非法字符的键或键,它会起作用。

答案 2 :(得分:3)

我会添加一个最终缓慢的&丑陋的解决方案,但仍然使用任何数量的数组项目的准备语句:) 3语句是任何情况下的通用,可以在任何地方重用。

  1. CREATE TEMPORARY TABLE {IDS {1}} ID为(
  2. INT ); ids INSERT INTO这将插入您的ID
  3. VALUES(?); id SELECT ids FROM使用其他表格中的数据对LEFT JOIN .... ;列表进行排序
  4. ids id SELECT ids FROM选择所有内容
  5. 否则,您必须使用;或手动对行进行排序。最好的想法是使用简单的MySQL查询,或者尝试获取已经按照自己喜欢的方式排序的ID列表。

答案 3 :(得分:3)

有同样的问题,除了7年前@sled的答案之外,这里有可能没有Document document = Jsoup.connect(url).get(); for (Element span : document.select("?").select("?")) { title = span.toString(); name.add(title); } 步骤,但只调用bind_params一次:

call_user_func_array(array($stmt, 'bind_param'), $ids);

答案 4 :(得分:1)

另一种方法是在结果对象上使用PHP usort函数,但这是“手动”。

看到这个: Sort Object in PHP

答案 5 :(得分:0)

不,如果您要使用ORDER BY子句从数据库中获取某些记录,则不建议这样做。

答案 6 :(得分:0)

您是否考虑使用JOIN和WHERE子句重写原始查询以获取您需要的IDS以避免需要WHERE IN子句?我带着同样的问题来到这里,在审查了可能的解决方案后,我意识到INNER JOIN是我的解决方案。