MySQL Order By
Как сортировать результаты MySQL-запросов в Python с помощью ORDER BY: по возрастанию, убыванию, нескольким столбцам, с WHERE и LIMIT.
В этой главе показано, как сортировать результаты MySQL-запросов в Python с помощью предложения ORDER BY. Вы узнаете, как выполнять сортировку по возрастанию и убыванию, по нескольким столбцам, комбинировать ORDER BY с WHERE и LIMIT, а также применять лучшие практики Python: параметризованные запросы и корректную обработку ошибок.
Что делает ORDER BY
Предложение ORDER BY указывает MySQL возвращать строки в заданном порядке, а не в порядке хранения (который непредсказуем). Можно сортировать по одному или нескольким столбцам в порядке возрастания (ASC) или убывания (DESC).
SELECT column1, column2
FROM table_name
ORDER BY column1 ASC, column2 DESC;Основные правила:
ASC(по возрастанию, A → Z, 0 → 9) — значение по умолчанию, его можно опустить.DESC(по убыванию, Z → A, 9 → 0) нужно указывать явно.- Несколько столбцов разделяются запятыми; MySQL сначала сортирует по первому столбцу, а второй используется для разрешения совпадений.
- Значения
NULLпри сортировкеASCидут перед не-NULL значениями, а приDESC— после них.
Требования
Вам понадобится пакет mysql-connector-python. Установите его один раз с помощью pip:
pip install mysql-connector-pythonВо всех примерах ниже предполагается наличие таблицы customers с как минимум столбцами id, name и address. Если вам нужно создать её, обратитесь к разделу Python MySQL – Create Table.
Сортировка по возрастанию (по умолчанию)
Порядок по возрастанию используется по умолчанию, поэтому ASC необязателен. Следующий запрос возвращает всех клиентов, отсортированных по имени в алфавитном порядке:
import mysql.connector
from mysql.connector import Error
try:
mydb = mysql.connector.connect(
host="localhost",
user="yourusername",
password="yourpassword",
database="mydatabase"
)
mycursor = mydb.cursor()
mycursor.execute("SELECT * FROM customers ORDER BY name")
for row in mycursor.fetchall():
print(row)
except Error as e:
print(f"Database error: {e}")
finally:
if mycursor:
mycursor.close()
if mydb.is_connected():
mydb.close()Блок try / except / finally гарантирует закрытие соединения даже при возникновении ошибки.
Сортировка по убыванию
Добавьте DESC после имени столбца, чтобы изменить порядок сортировки на обратный. Этот запрос возвращает клиентов, отсортированных от Z до A:
import mysql.connector
from mysql.connector import Error
try:
mydb = mysql.connector.connect(
host="localhost",
user="yourusername",
password="yourpassword",
database="mydatabase"
)
mycursor = mydb.cursor()
mycursor.execute("SELECT * FROM customers ORDER BY name DESC")
for row in mycursor.fetchall():
print(row)
except Error as e:
print(f"Database error: {e}")
finally:
if mycursor:
mycursor.close()
if mydb.is_connected():
mydb.close()Сортировка по нескольким столбцам
Когда в первом столбце сортировки встречаются одинаковые значения, MySQL использует второй столбец для их разрешения. Это удобно, например, когда нужно отсортировать клиентов сначала по городу, а затем по имени в пределах каждого города:
import mysql.connector
from mysql.connector import Error
try:
mydb = mysql.connector.connect(
host="localhost",
user="yourusername",
password="yourpassword",
database="mydatabase"
)
mycursor = mydb.cursor()
# Sort by address (city) ascending, then by name ascending within each city
mycursor.execute("SELECT * FROM customers ORDER BY address ASC, name ASC")
for row in mycursor.fetchall():
print(row)
except Error as e:
print(f"Database error: {e}")
finally:
if mycursor:
mycursor.close()
if mydb.is_connected():
mydb.close()Каждый столбец в многоколоночной сортировке может иметь собственное направление:
-- Most recent orders first; within the same date, highest total first
SELECT * FROM orders ORDER BY order_date DESC, total_amount DESC;Комбинирование ORDER BY с WHERE
ORDER BY применяется после того, как WHERE отфильтровал строки. Используйте параметризованные запросы (заполнитель %s), чтобы безопасно передавать значения — никогда не вставляйте пользовательский ввод напрямую в SQL-строку.
import mysql.connector
from mysql.connector import Error
try:
mydb = mysql.connector.connect(
host="localhost",
user="yourusername",
password="yourpassword",
database="mydatabase"
)
mycursor = mydb.cursor()
# Find all customers in London, sorted by name
sql = "SELECT * FROM customers WHERE address = %s ORDER BY name ASC"
val = ("London",)
mycursor.execute(sql, val)
for row in mycursor.fetchall():
print(row)
except Error as e:
print(f"Database error: {e}")
finally:
if mycursor:
mycursor.close()
if mydb.is_connected():
mydb.close()Заполнитель %s подставляется самим MySQL (а не форматированием строк Python), что предотвращает SQL-инъекции независимо от содержимого значения.
Комбинирование ORDER BY с LIMIT
Используйте LIMIT вместе с ORDER BY для реализации шаблонов вроде «топ N записей» или постраничного вывода. Порядок сортировки в SQL-запросе должен стоять перед LIMIT.
import mysql.connector
from mysql.connector import Error
try:
mydb = mysql.connector.connect(
host="localhost",
user="yourusername",
password="yourpassword",
database="mydatabase"
)
mycursor = mydb.cursor()
# The 5 customers whose names come first alphabetically
mycursor.execute("SELECT * FROM customers ORDER BY name ASC LIMIT 5")
for row in mycursor.fetchall():
print(row)
except Error as e:
print(f"Database error: {e}")
finally:
if mycursor:
mycursor.close()
if mydb.is_connected():
mydb.close()Для постраничного вывода (пропуска предыдущих страниц) добавьте OFFSET:
-- Page 2: rows 6–10
SELECT * FROM customers ORDER BY name ASC LIMIT 5 OFFSET 5;Подробное описание LIMIT и OFFSET см. в разделе Python MySQL – Limit.
fetchone, fetchall и fetchmany
После выполнения запроса с ORDER BY результаты можно получить разными способами:
| Метод | Возвращает | Когда использовать |
|---|---|---|
fetchall() | Список всех подходящих кортежей | Результирующий набор достаточно мал, чтобы поместиться в памяти |
fetchone() | Первую строку в виде кортежа (или None) | Нужна только верхняя запись |
fetchmany(n) | Список из следующих n строк | Обработка большого результата по частям |
Пример — получение только первого клиента в алфавитном порядке:
mycursor.execute("SELECT * FROM customers ORDER BY name ASC")
top = mycursor.fetchone()
print(top) # e.g. (1, 'Alice', 'London')Распространённые ошибки
Сортировка чисел, хранящихся как строки. Если в столбце числа хранятся как VARCHAR, MySQL сортирует их лексикографически ('10' идёт перед '9'). Приводите столбец к числовому типу, когда нужна числовая сортировка:
SELECT * FROM products ORDER BY CAST(price AS DECIMAL(10,2)) ASC;Сортировка без ORDER BY недетерминирована. MySQL не гарантирует порядок строк без указания ORDER BY. Полагаться на порядок вставки ненадёжно — он непредсказуемо изменится по мере роста таблицы или изменения индексов.
Псевдонимы столбцов работают в ORDER BY. Если в SELECT задан псевдоним, его можно использовать в ORDER BY:
SELECT name, address AS city FROM customers ORDER BY city ASC;Позиция в ORDER BY. Можно ссылаться на столбец по его позиции в списке SELECT (например, ORDER BY 1), но это хрупкое решение — избегайте его в рабочем коде, так как оно молча ломается при изменении порядка столбцов.
Связанные разделы
- Python MySQL – Get Started — установка коннектора и подключение к MySQL
- Python MySQL – Select — чтение данных с помощью
SELECT - Python MySQL – Where — фильтрация строк с помощью
WHERE - Python MySQL – Limit — ограничение количества результатов с помощью
LIMIT - Python MySQL – Join — объединение данных из нескольких таблиц