Eine vorbereitete statement, `WHERE .. IN (..)` Abfrage und Sortierung – mit MySQL

Stellen Sie sich vor, wir haben eine Frage:

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

und ein Array von IDs zum Abrufen: $ids = array(1,5,18,25)

Mit vorbereiteten Aussagen ist es ratsam , eine Aussage vorzubereiten und sie mehrfach aufzurufen:

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

Aber jetzt muss ich die Ergebnisse manuell sortieren. Habe ich schöne Alternativen?

Du könntest es so machen:

 $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 

Mit diesem Aufruf rufen Sie bind_param für jede ID auf und Sie sortieren nach mysql.

Ich glaube, das ist die einfachste mögliche Antwort:

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

Solange Ihr Array von IDs keine Schlüssel oder Schlüssel mit ungültigen Zeichen enthält, wird es funktionieren.

Ich füge eine letztlich langsame & hässliche Lösung hinzu, die dennoch vorbereitete statementen für eine beliebige Anzahl von Array-Elementen verwendet 🙂 3 statementen sind universell für jeden Fall und können überall wiederverwendet werden.

  1. CREATE TEMPORARY TABLE IDs ( id INT );
  2. INSERT INTO VALUES(?); Dies wird Ihre IDs einfügen
  3. SELECT ID FROM IDS LEFT JOIN .... ; Verwenden Sie Daten aus anderen Tabellen, um die ids Liste zu sortieren
  4. SELECT ID FROM IDs ; wähle alles zurück

Andernfalls müssen Sie IN (?,?,?,.... oder die Zeilen manuell sortieren. Am besten verwenden Sie einfache MySQL-Abfragen oder versuchen Sie, die Liste der bereits sortierten IDs abzurufen du magst.

Hatte das gleiche Problem und zusätzlich zu der Antwort von @sled vor 7 Jahren, hier ist eine Möglichkeit, ohne das call_user_func_array(array($stmt, 'bind_param'), $ids); Schritt, aber rufen Sie bind_params nur einmal auf:

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

Eine Alternative wäre, PHP-Usort-function für das Ergebnisobjekt zu verwenden, aber das ist “manuell”.

Siehe hierzu: Objekt in PHP sortieren

Nein, es wird nicht empfohlen, wenn Sie mithilfe der ORDER BY Klausel bestimmte Datensätze aus der database ORDER BY .

Haben Sie erwogen, Ihre ursprüngliche Abfrage mit einer JOIN- und WHERE-Klausel neu zu schreiben, um die IDS zu erhalten, die Sie benötigen, um die Notwendigkeit einer WHERE IN-Klausel zu vermeiden? Ich kam mit der gleichen Frage hierher und nachdem ich die möglichen Lösungen überprüft hatte, erkannte ich, dass ein INNER JOIN meine Lösung war.