Die MySQL ORDER BY-Klausel in PHP verstehen
Die ORDER BY-Klausel sortiert Abfrageergebnisse in PHP nach einer oder mehreren Spalten – aufsteigend, absteigend oder kombiniert.
Eine SELECT-Abfrage ohne ORDER BY gibt Zeilen in einer Reihenfolge zurück, die MySQL nicht garantiert — sie kann sich zwischen Ausführungen, Serverversionen oder nach Tabellenwartungen ändern. Die ORDER BY-Klausel macht diese Reihenfolge explizit und sortiert das Ergebnis nach einer oder mehreren Spalten. Diese Seite zeigt, wie man sie in PHP verwendet: die Syntax, aufsteigendes und absteigendes Sortieren, Sortieren nach mehreren Spalten, wo NULL-Werte landen, und wie man nach einer vom Benutzer angegebenen Spalte sicher sortiert, ohne eine SQL-Injection-Lücke zu öffnen.
Wenn Sie neu im Ausführen von Abfragen aus PHP sind, beginnen Sie zuerst mit Verbindung zu MySQL und Daten auswählen.
Syntax
SELECT column1, column2, ...
FROM table_name
ORDER BY column1 [ASC | DESC], column2 [ASC | DESC], ...;ASCsortiert aufsteigend (A→Z, 0→9, ältestes→neuestes) und ist der Standard —ORDER BY ageundORDER BY age ASCsind identisch.DESCsortiert absteigend (Z→A, 9→0, neuestes→ältestes).- Die Richtung gilt pro Spalte, sodass man sie mischen kann:
ORDER BY country ASC, age DESC.
ORDER BY wird nach der WHERE-Filterung und GROUP BY ausgeführt, sortiert also nur die Zeilen, die diese Schritte überlebt haben. Es ist die letzte Klausel vor LIMIT.
Ein einfaches Beispiel
Dies wählt Namen und Alter aus und sortiert die ältesten Kunden zuerst:
<?php
$conn = new mysqli("localhost", "username", "password", "database");
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT name, age FROM customers ORDER BY age DESC";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
while ($row = $result->fetch_assoc()) {
echo "Name: " . $row["name"] . " - Age: " . $row["age"] . "<br>";
}
} else {
echo "0 results";
}
$conn->close();
?>Wir verbinden uns mit der mysqli-Klasse, wählen name und age aus customers aus und verwenden ORDER BY age DESC, damit das höchste Alter zuerst erscheint. Ersetzen Sie DESC durch ASC (oder lassen Sie es weg), um die Jüngsten zuerst anzuzeigen.
Sortieren nach mehreren Spalten
Wenn mehrere Zeilen denselben Wert in der ersten Sortierspalte haben, bricht die nächste Spalte das Gleichstand. Die Reihenfolge der Spalten in der Klausel ist die Rangfolge:
SELECT name, country, age
FROM customers
ORDER BY country ASC, age DESC;Dies gruppiert Kunden alphabetisch nach country und listet innerhalb jedes Landes die Ältesten zuerst. Mit den folgenden Daten:
| Name | Land | Alter |
|---|---|---|
| Anna | Canada | 41 |
| Ben | Canada | 29 |
| Carla | Mexico | 50 |
ORDER BY country ASC, age DESC gibt Anna, Ben, Carla zurück — Canada vor Mexico, und Anna vor Ben, weil 41 > 29.
Wie NULL-Werte sortiert werden
In MySQL wird NULL als kleiner als jeder Nicht-NULL-Wert behandelt:
- Mit
ASCerscheinen Zeilen, bei denen die SortierspalteNULList, zuerst. - Mit
DESCerscheinen sie zuletzt.
Um NULL-Werte unabhängig von der Richtung ans Ende zu verschieben, sortiert man zuerst danach, ob die Spalte null ist:
SELECT name, last_login
FROM users
ORDER BY last_login IS NULL, last_login DESC;last_login IS NULL ergibt 0 für echte Datumsangaben und 1 für Nulls, sodass die Nicht-null-Zeilen (0) vor den Null-Zeilen (1) erscheinen.
Sicheres Sortieren nach einer zur Laufzeit gewählten Spalte
Ein häufiger Bedarf ist es, dem Benutzer die Auswahl der Sortierspalte zu ermöglichen — zum Beispiel ?sort=name. Man kann einen Spaltennamen oder das ASC/DESC-Schlüsselwort nicht mit einem Prepared-Statement-Platzhalter binden; Platzhalter funktionieren nur für Werte. Die rohe Anfrage in das SQL einzufügen wäre eine SQL-Injection-Schwachstelle. Stattdessen validiert man die Eingabe gegen eine Allow-List:
<?php
// Map user input to known-good column names.
$allowedColumns = [
"name" => "name",
"age" => "age",
"date" => "created_at",
];
$sortKey = $_GET["sort"] ?? "name";
$column = $allowedColumns[$sortKey] ?? "name"; // fallback if unknown
$direction = (($_GET["dir"] ?? "asc") === "desc") ? "DESC" : "ASC";
// $column and $direction can now only be values we put in the code.
$sql = "SELECT name, age FROM customers ORDER BY $column $direction";
$result = $conn->query($sql);
?>Der Benutzer liefert nur einen Array-Schlüssel; der tatsächliche Spaltenname und die Richtung stammen aus Konstanten im eigenen Code, sodass nicht vertrauenswürdige Eingaben niemals den Abfragestring erreichen. Dies ist der einzige Ort, an dem das Erstellen von SQL durch Verkettung akzeptabel ist — weil jeder mögliche Wert einer ist, den man selbst verfasst hat.
Hinweis:
ORDER BYselbst verarbeitet nie Benutzer-Werte, verwendet daher keine gebundenen Parameter. AlleWHERE-Werte in derselben Abfrage sollten dennoch mit einem Prepared Statement gebunden werden.
Häufige Fallstricke
- Sortieren nach einer String-Spalte mit Zahlen (z. B. ein als
VARCHARgespeichertesage) sortiert lexikalisch:"10"kommt vor"9". Zahlen in einer numerischen Spalte speichern oder mitORDER BY CAST(age AS UNSIGNED)umwandeln. ORDER BYmitLIMITermöglicht "Top-N"-Ergebnisse:ORDER BY age DESC LIMIT 5gibt die fünf Ältesten zurück. OhneORDER BYsind die Zeilen, dieLIMITbehält, unvorhersehbar. Siehe Daten begrenzen.- Das Sortieren eines großen Ergebnissatzes kann langsam sein, wenn kein Index die Sortierspalte abdeckt; ein Index auf der
ORDER BY-Spalte ermöglicht es MySQL, den Sortierschritt zu überspringen.
Fazit
ORDER BY verwandelt eine undefinierte Zeilenreihenfolge in eine definierte. Merken Sie sich das Wesentliche: ASC ist der Standard, Spalten werden von links nach rechts zur Gleichstandsauflösung angewendet, NULL sortiert niedrig, und eine vom Benutzer gewählte Sortierspalte muss gegen eine Allow-List validiert und nicht blind verkettet werden. Kombiniert mit WHERE zum Filtern und LIMIT zur Seitenaufteilung erhalten Sie die volle Kontrolle darüber, welche Zeilen in welcher Reihenfolge zurückgegeben werden.