用MySQL准备的语句“WHERE IN(..)”查询和sorting
想象一下,我们有一个查询:
SELECT * FROM somewhere WHERE `id` IN(1,5,18,25) ORDER BY `name`;
和一个ID数组来获取: $ids = array(1,5,18,25)
通过准备好的陈述, build议您准备一个陈述并多次调用它:
$stmt = $mysqli->prepare('SELECT * FROM somewhere WHERE `id`=?;'); foreach ($ids as $id){ $stmt->bind_params('i', $id); $stmt->exec(); }
但现在我必须手动sorting结果。 我有什么好的select吗?
你可以这样做:
$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为每个id,你有sorting完成的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();
只要你的ID数组不包含非法字符的键或键,它将工作。
不,不build议使用ORDER BY
子句从数据库中获取某些logging。
另一种方法是在结果对象上使用PHP usort函数,但这是“手动的”。
看到这个: 在PHP中sorting对象
我将添加一个最终缓慢和丑陋的解决scheme,但是使用准备好的语句来处理任意数量的数组项目:) 3个语句对于任何情况都是通用的,并且可以在任何地方重复使用。
-
CREATE TEMPORARY TABLE
ids(
idINT );
-
INSERT INTO
idsVALUES(?);
这会插入你的ID -
SELECT
idFROM
IDSLEFT JOIN .... ;
使用来自其他表格的数据对ids
列表进行sorting -
SELECT
idFROM
ids;
select一切回来
否则,你将不得不使用IN (?,?,?,....
或者手动sorting行。最好的办法是使用简单的MySQL查询,或者尝试获取已经sorting的ID列表你喜欢。
有相同的问题,除了7年前的@sled的答案,这里是没有做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子句? 我带着同样的问题来到这里,在回顾了可能的解决scheme之后,我意识到INNER JOIN是我的解决scheme。